public void testJTAEnlistment()

in geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java [6370:6582]


  public void testJTAEnlistment() throws CacheException, javax.transaction.NotSupportedException,
      javax.transaction.RollbackException, javax.transaction.SystemException,
      javax.transaction.HeuristicMixedException, javax.transaction.HeuristicRollbackException {

    TransactionListener tl = new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        ++listenerAfterCommit;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        ++listenerAfterFailedCommit;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        ++listenerAfterRollback;
        te = event;
      }

      @Override
      public void close() {
        ++listenerClose;
      }
    };

    txMgr.addListener(tl);

    javax.transaction.UserTransaction userTx = null;
    try {
      userTx = (javax.transaction.UserTransaction) cache.getJNDIContext()
          .lookup("java:/UserTransaction");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable badDog) {
      fail("Expected to get a healthy UserTransaction!");
    }

    // Test enlistment for put
    // Test enlisted rollback
    // Test prevention of rollback/commit for enlisted transaction
    assertEquals(0, listenerAfterRollback);
    userTx.begin();
    region.put("enlistKey", "enlistVal");
    assertEquals("enlistVal", region.getEntry("enlistKey").getValue());
    assertNotNull(txMgr.getTransactionId());
    try {
      txMgr.rollback();
      fail("Should not allow a CacheTransactionManager.rollback call once the GF Tx is enlisted");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable ignored) {
    }

    try {
      txMgr.commit();
      fail("Should not allow a CacheTransactionManager.commit() call once the GF Tx is enlisted");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable ignored) {
    }
    userTx.rollback();
    assertNull(txMgr.getTransactionId());
    assertTrue(!region.containsKey("enlistKey"));
    assertEquals(1, listenerAfterRollback);

    // Test enlistment for create
    // Test commit
    assertEquals(0, listenerAfterCommit);
    userTx.begin();
    region.create("enlistKey", "enlistVal");
    assertEquals("enlistVal", region.getEntry("enlistKey").getValue());
    assertNotNull(txMgr.getTransactionId());
    userTx.commit();
    assertNull(txMgr.getTransactionId());
    assertTrue(region.containsKey("enlistKey"));
    assertEquals("enlistVal", region.getEntry("enlistKey").getValue());
    assertEquals(1, listenerAfterCommit);

    // Test enlistment for get
    assertEquals(1, listenerAfterCommit);
    userTx.begin();
    assertEquals("enlistVal", region.get("enlistKey"));
    assertNotNull(txMgr.getTransactionId());
    userTx.commit();
    assertNull(txMgr.getTransactionId());
    assertEquals(2, listenerAfterCommit);

    // Test enlistment for invalidate
    assertEquals(2, listenerAfterCommit);
    userTx.begin();
    region.invalidate("enlistKey");
    assertTrue(region.containsKey("enlistKey"));
    assertTrue(!region.containsValueForKey("enlistKey"));
    assertNotNull(txMgr.getTransactionId());
    userTx.commit();
    assertNull(txMgr.getTransactionId());
    assertTrue(region.containsKey("enlistKey"));
    assertTrue(!region.containsValueForKey("enlistKey"));
    assertEquals(3, listenerAfterCommit);

    // Test enlistment for destroy
    assertEquals(3, listenerAfterCommit);
    userTx.begin();
    region.destroy("enlistKey");
    assertTrue(!region.containsKey("enlistKey"));
    assertNotNull(txMgr.getTransactionId());
    userTx.commit();
    assertNull(txMgr.getTransactionId());
    assertTrue(!region.containsKey("enlistKey"));
    assertEquals(4, listenerAfterCommit);

    // Test enlistment for load
    AttributesMutator<String, String> mutator = region.getAttributesMutator();
    mutator.setCacheLoader(new CacheLoader<String, String>() {
      int count = 0;

      @Override
      public String load(LoaderHelper helper) throws CacheLoaderException {
        return String.valueOf(count++);
      }

      @Override
      public void close() {}
    });
    assertEquals(4, listenerAfterCommit);
    userTx.begin();
    assertEquals("0", region.get("enlistKey"));
    assertNotNull(txMgr.getTransactionId());
    userTx.commit();
    assertNull(txMgr.getTransactionId());
    assertTrue(region.containsKey("enlistKey"));
    assertEquals("0", region.getEntry("enlistKey").getValue());
    assertEquals(5, listenerAfterCommit);
    mutator.setCacheLoader(null);

    // Test enlisted failed commit
    assertEquals(0, listenerAfterFailedCommit);
    userTx.begin();
    region.put("enlistKey", "enlistVal");
    assertEquals("enlistVal", region.get("enlistKey"));
    assertNotNull(txMgr.getTransactionId());
    {
      TXManagerImpl gfTxMgrImpl = (TXManagerImpl) txMgr;
      TXStateProxy gfTx = gfTxMgrImpl.pauseTransaction();

      javax.transaction.TransactionManager jtaTxMgr = cache.getJTATransactionManager();
      javax.transaction.Transaction jtaTx = jtaTxMgr.suspend();

      region.put("enlistKey", "conflictVal");
      assertEquals("conflictVal", region.get("enlistKey"));

      try {
        jtaTxMgr.resume(jtaTx);
      } catch (Exception failure) {
        fail("JTA resume failed");
      }
      gfTxMgrImpl.unpauseTransaction(gfTx);
    }
    assertEquals("enlistVal", region.get("enlistKey"));
    try {
      userTx.commit();
      fail("Expected JTA commit exception!");
    } catch (javax.transaction.HeuristicRollbackException ignored) {
    } catch (javax.transaction.RollbackException ignored) {
    } catch (Exception yuk) {
      fail("Did not expect this exception from JTA commit: " + yuk);
    }
    assertNull(txMgr.getTransactionId());
    assertEquals("conflictVal", region.getEntry("enlistKey").getValue());
    assertEquals(1, listenerAfterFailedCommit);

    // Test rollbackOnly UserTransaction enlistment
    userTx.begin();
    assertNull(txMgr.getTransactionId());
    userTx.setRollbackOnly();
    assertEquals(javax.transaction.Status.STATUS_MARKED_ROLLBACK, userTx.getStatus());
    try {
      region.put("enlistKey", "enlistVal2");
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException ignored) {
    }
    assertNull(txMgr.getTransactionId());
    try {
      assertEquals("conflictVal", region.getEntry("enlistKey").getValue());
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException ignored) {
    }
    assertTrue(!region.containsKey("enlistKey2"));
    try {
      region.put("enlistKey2", "enlistVal3");
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException ignored) {
    }
    assertNull(txMgr.getTransactionId());
    try {
      assertEquals("conflictVal", region.getEntry("enlistKey").getValue());
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException ignored) {
    }
    assertTrue(!region.containsKey("enlistKey2"));
    userTx.rollback();
    assertEquals("conflictVal", region.getEntry("enlistKey").getValue());
    assertTrue(!region.containsKey("enlistKey2"));

    txMgr.removeListener(tl);
  }