public void testDelistErrorAndUnilateralRollbackOnCommit() 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();
    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

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

    // 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());
  }
  protected void setUp() throws Exception {
    EventRecorder.clear();

    // change disk journal into mock journal
    Field field = TransactionManagerServices.class.getDeclaredField("journalRef");
    field.setAccessible(true);
    AtomicReference<Journal> journalRef =
        (AtomicReference<Journal>) field.get(TransactionManagerServices.class);
    journalRef.set(new MockJournal());

    poolingDataSource1 = new PoolingDataSource();
    poolingDataSource1.setClassName(MockitoXADataSource.class.getName());
    poolingDataSource1.setUniqueName("pds1");
    poolingDataSource1.setMinPoolSize(5);
    poolingDataSource1.setMaxPoolSize(5);
    poolingDataSource1.setAutomaticEnlistingEnabled(true);
    poolingDataSource1.init();

    poolingDataSource2 = new PoolingDataSource();
    poolingDataSource2.setClassName(MockitoXADataSource.class.getName());
    poolingDataSource2.setUniqueName("pds2");
    poolingDataSource2.setMinPoolSize(5);
    poolingDataSource2.setMaxPoolSize(5);
    poolingDataSource2.setAutomaticEnlistingEnabled(true);
    poolingDataSource2.init();

    btm = TransactionManagerServices.getTransactionManager();
  }