public void testDelistUnilateralRollbackOnCommit() throws Exception {
    btm.begin();

    Connection connection1 = poolingDataSource1.getConnection();
    JdbcConnectionHandle handle1 = (JdbcConnectionHandle) Proxy.getInvocationHandler(connection1);
    XAConnection xaConnection1 =
        (XAConnection) AbstractMockJdbcTest.getWrappedXAConnectionOf(handle1.getPooledConnection());
    MockXAResource xaResource1 = (MockXAResource) xaConnection1.getXAResource();
    connection1.createStatement();

    xaResource1.setEndException(
        new BitronixXAException("what was that transaction again?", XAException.XAER_NOTA));
    xaResource1.setRollbackException(
        new BitronixXAException(
            "delistment unilaterally rolled back, cannot rollback twice", XAException.XAER_RMERR));

    Connection connection2 = poolingDataSource2.getConnection();
    JdbcConnectionHandle handle2 = (JdbcConnectionHandle) Proxy.getInvocationHandler(connection2);
    XAConnection xaConnection2 =
        (XAConnection) AbstractMockJdbcTest.getWrappedXAConnectionOf(handle2.getPooledConnection());
    MockXAResource xaResource2 = (MockXAResource) xaConnection2.getXAResource();
    connection2.createStatement(); // triggers enlistment

    try {
      btm.commit();
      fail("expected RollbackException");
    } catch (RollbackException ex) {
      assertEquals(
          "delistment error caused transaction rollback"
              + System.getProperty("line.separator")
              + "  resource(s) [pds1] unilaterally rolled back",
          ex.getMessage());
    }

    // check flow
    List orderedEvents = EventRecorder.getOrderedEvents();
    log.info(EventRecorder.dumpToString());

    assertEquals(9, orderedEvents.size());
    int i = 0;
    assertEquals(Status.STATUS_ACTIVE, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
    assertEquals(XAResource.TMNOFLAGS, ((XAResourceStartEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(XAResource.TMNOFLAGS, ((XAResourceStartEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(XAResource.TMSUCCESS, ((XAResourceEndEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(
        Status.STATUS_MARKED_ROLLBACK, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
    assertEquals(XAResource.TMSUCCESS, ((XAResourceEndEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(
        Status.STATUS_ROLLING_BACK, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
    assertTrue(((XAResourceRollbackEvent) orderedEvents.get(i++)).getSource() == xaResource2);
    assertEquals(Status.STATUS_ROLLEDBACK, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
  }
  public void testDelistErrorAndUnilateralRollbackOnRollback() throws Exception {
    btm.begin();

    Connection connection1 = poolingDataSource1.getConnection();
    JdbcConnectionHandle handle = (JdbcConnectionHandle) Proxy.getInvocationHandler(connection1);
    XAConnection xaConnection1 =
        (XAConnection) AbstractMockJdbcTest.getWrappedXAConnectionOf(handle.getPooledConnection());
    MockXAResource xaResource1 = (MockXAResource) xaConnection1.getXAResource();
    xaResource1.setEndException(
        new BitronixXAException("screw delistment", XAException.XAER_RMERR));
    xaResource1.setRollbackException(
        new BitronixXAException("delistment was screwed, cannot rollback", XAException.XAER_RMERR));

    connection1.createStatement(); // triggers enlistment

    Connection connection2 = poolingDataSource2.getConnection();
    JdbcConnectionHandle handle2 = (JdbcConnectionHandle) Proxy.getInvocationHandler(connection2);
    XAConnection xaConnection2 =
        (XAConnection) AbstractMockJdbcTest.getWrappedXAConnectionOf(handle2.getPooledConnection());
    MockXAResource xaResource2 = (MockXAResource) xaConnection2.getXAResource();
    xaResource2.setEndException(
        new BitronixXAException("what was that transaction again?", XAException.XAER_NOTA));
    xaResource2.setRollbackException(
        new BitronixXAException(
            "delistment unilaterally rolled back, cannot rollback twice", XAException.XAER_RMERR));

    connection2.createStatement(); // triggers enlistment

    btm.rollback();

    log.info(EventRecorder.dumpToString());

    // check flow
    List orderedEvents = EventRecorder.getOrderedEvents();
    log.info(EventRecorder.dumpToString());

    assertEquals(8, orderedEvents.size());
    int i = 0;
    assertEquals(Status.STATUS_ACTIVE, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
    assertEquals(XAResource.TMNOFLAGS, ((XAResourceStartEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(XAResource.TMNOFLAGS, ((XAResourceStartEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(XAResource.TMSUCCESS, ((XAResourceEndEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(
        Status.STATUS_MARKED_ROLLBACK, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
    assertEquals(XAResource.TMSUCCESS, ((XAResourceEndEvent) orderedEvents.get(i++)).getFlag());
    assertEquals(
        Status.STATUS_ROLLING_BACK, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
    assertEquals(Status.STATUS_ROLLEDBACK, ((JournalLogEvent) orderedEvents.get(i++)).getStatus());
  }