[jboss-svn-commits] JBL Code SVN: r26856 - in labs/jbosstm/trunk/ArjunaJTA/jta: classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jun 5 11:05:00 EDT 2009


Author: jhalliday
Date: 2009-06-05 11:04:59 -0400 (Fri, 05 Jun 2009)
New Revision: 26856

Modified:
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/spi/XATerminatorExtensions.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java
   labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java
   labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/TestSynchronization.java
Log:
javadoc improvements and test cases for doBeforeCompletion methods. JBTM-560


Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/spi/XATerminatorExtensions.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/spi/XATerminatorExtensions.java	2009-06-05 14:40:24 UTC (rev 26855)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/spi/XATerminatorExtensions.java	2009-06-05 15:04:59 UTC (rev 26856)
@@ -1,28 +1,28 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
- * as indicated by the @author tags. 
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
  * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
+ * full listing of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
  * You should have received a copy of the GNU Lesser General Public License,
  * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
 /*
  * Copyright (C) 2004,
- * 
+ *
  * Arjuna Technologies Ltd, Newcastle upon Tyne, Tyne and Wear, UK.
- * 
+ *
  * $Id: XAResourceErrorHandler.java 2342 2006-03-30 13:06:17Z  $
  */
 
@@ -34,13 +34,13 @@
  * Extensions to the basic XATerminator spi interface. It is important that
  * these extensions aren't relied on to drive the normal JCA protocol in case
  * we're ever embedded in a foreign implementation.
- * 
+ *
  * It would be nice to have these non-XA specific extensions managed by a different
  * class than the one that deals with the standard XATerminator interface methods,
  * c.f. JTS/OTS for 2PC and Synchronizations. However, it's a lot easier to just bundle
  * these together in the same implementation because of the way JCA works. Of course that can
  * be changed later if necessary and the user(s) won't notice anyway.
- * 
+ *
  * @author marklittle
  */
 
@@ -51,18 +51,21 @@
      * handled by a separate instance, as well as being architecturally symmetrical with
      * OTS. But it's not a big deal. Plus, this isn't really symmetrical either, since we
      * don't need afterCompletion.
-     * 
+     *
      * TODO check whether it makes sense to resurrect afterCompletion here for, say,
      * compensations.
      */
-    
+
     /**
      * Call beforeCompletion on the registered instance. Exceptions will cause the transaction
-     * to rollback.
-     * 
+     * to be set rollback only.
+     *
+     * Note: this will run beforeCompletion even on setRollbackOnly transactions.
+     * Users may wish to avoid calling this method in such cases, or prior to calling rollback.
+     *
      * @param xid the transaction instance.
      * @return success (or not).
      */
-    
+
     public boolean beforeCompletion (Xid xid) throws javax.transaction.SystemException;
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java	2009-06-05 14:40:24 UTC (rev 26855)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java	2009-06-05 15:04:59 UTC (rev 26856)
@@ -38,7 +38,7 @@
 	 * @return a TwoPhaseOutcome representing the result.
 	 */
     public int doPrepare();
-    
+
 	/**
 	 * Drive the subordinate transaction to commit. It must have previously
 	 * been prepared.
@@ -53,7 +53,7 @@
     public void doCommit () throws IllegalStateException,
 			HeuristicMixedException, HeuristicRollbackException, HeuristicCommitException,
 			SystemException;
-        
+
 	/**
 	 * Drive the subordinate transaction to roll back. It need not have been previously
 	 * prepared.
@@ -69,7 +69,7 @@
 	 */
     public void doRollback () throws IllegalStateException,
             HeuristicMixedException, HeuristicCommitException, HeuristicRollbackException, SystemException;
-    
+
 	/**
 	 * Drive the transaction to commit. It should not have been previously
 	 * prepared and will be the only resource in the global transaction.
@@ -80,7 +80,7 @@
 	 */
     public void doOnePhaseCommit () throws IllegalStateException,
 			HeuristicMixedException, SystemException, RollbackException;
-    
+
 	/**
 	 * Called to tell the transaction to forget any heuristics.
 	 *
@@ -91,17 +91,19 @@
 
     /**
      * Run beforeCompletion on Synchronizations.
-     * 
+     * Note: this will run beforeCompletion even on setRollbackOnly transactions.
+     * Users may wish to avoid calling this method in such cases, or prior to calling rollback.
+     *
      * @return outcome
      */
-    
+
     public boolean doBeforeCompletion () throws SystemException;
 
     public boolean activated();
-    
+
     public void recover();
-    
+
     public Xid baseXid();
-    
+
     public Uid get_uid();
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java	2009-06-05 14:40:24 UTC (rev 26855)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java	2009-06-05 15:04:59 UTC (rev 26856)
@@ -28,10 +28,12 @@
 import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
 import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
 import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
+import com.arjuna.ats.internal.jta.resources.spi.XATerminatorExtensions;
 import com.arjuna.ats.jta.xa.XidImple;
 
 import javax.transaction.RollbackException;
 import javax.transaction.Transaction;
+import javax.transaction.Status;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 import javax.transaction.xa.XAException;
@@ -45,7 +47,6 @@
         return new TransactionImple(0); // implicit begin
     }
 
-    
 	public void testCleanupCommit () throws Exception
 	{
 		for (int i = 0; i < 1000; i++)
@@ -276,4 +277,205 @@
         assertTrue(sync.isAfterCompletionDone());
         assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
     }
+
+    /////////////
+
+    public void testOnePhaseCommitSyncWithSeparateSync() throws Exception
+    {
+        final SubordinateTransaction tm = createTransaction();
+        final TestSynchronization sync = new TestSynchronization();
+        tm.registerSynchronization(sync);
+        tm.doBeforeCompletion();
+        tm.doOnePhaseCommit();
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
+    }
+
+    public void testOnePhaseCommitSyncViaXATerminatorWithSeparateSync() throws Exception
+    {
+        final Xid xid = new XidImple(new Uid());
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+        final TestSynchronization sync = new TestSynchronization();
+        t.registerSynchronization(sync);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+        final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions)xaTerminator;
+        xaTerminatorExtensions.beforeCompletion(xid);
+        xaTerminator.commit(xid, true);
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, t.getStatus());
+    }
+
+    public void testOnePhaseCommitSyncWithRollbackOnlyWithSeparateSync() throws Exception
+    {
+        final SubordinateTransaction tm = createTransaction();
+        final TestSynchronization sync = new TestSynchronization();
+        tm.registerSynchronization(sync);
+        tm.setRollbackOnly();
+        tm.doBeforeCompletion();
+        try {
+            tm.doOnePhaseCommit();
+            fail("did not get expected rollback exception");
+        } catch(RollbackException e) {
+            // expected - we tried to commit a rollbackonly tx.
+        }
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, tm.getStatus());
+    }
+
+    public void testOnePhaseCommitSyncWithRollbackOnlyViaXATerminatorWithSeparateSync() throws Exception
+    {
+        final Xid xid = new XidImple(new Uid());
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+        final TestSynchronization sync = new TestSynchronization();
+        t.registerSynchronization(sync);
+        t.setRollbackOnly();
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+        final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions)xaTerminator;
+        xaTerminatorExtensions.beforeCompletion(xid);
+        try {
+            xaTerminator.commit(xid, true);
+            ((TransactionImple)t).doOnePhaseCommit();
+            fail("did not get expected rollback exception");
+        } catch(XAException e) {
+            assertEquals("javax.transaction.RollbackException", e.getCause().getClass().getName());
+            assertEquals(XAException.XA_RBROLLBACK, e.errorCode);
+            // expected - we tried to commit a rollbackonly tx.
+        }
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
+    }
+
+    public void testRollbackSyncWithSeparateSync() throws Exception
+    {
+        final SubordinateTransaction tm = createTransaction();
+        final TestSynchronization sync = new TestSynchronization();
+        tm.registerSynchronization(sync);
+        tm.doBeforeCompletion();
+        tm.doRollback();
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, tm.getStatus());
+    }
+
+    public void testRollbackSyncViaXATerminatorWithSeparateSync() throws Exception
+    {
+        final Xid xid = new XidImple(new Uid());
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+        final TestSynchronization sync = new TestSynchronization();
+        t.registerSynchronization(sync);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+        final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions)xaTerminator;
+        xaTerminatorExtensions.beforeCompletion(xid);
+        xaTerminator.rollback(xid);
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
+    }
+
+
+    public void testTwoPhaseCommitSyncWithSeparateSync() throws Exception
+    {
+        final SubordinateTransaction tm = createTransaction();
+        final TestSynchronization sync = new TestSynchronization();
+        tm.registerSynchronization(sync);
+        tm.doBeforeCompletion();
+        assertEquals(TwoPhaseOutcome.PREPARE_READONLY, tm.doPrepare());
+        tm.doCommit();
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
+    }
+
+    public void testTwoPhaseCommitSyncViaXATerminatorWithSeparateSync() throws Exception
+    {
+        final Xid xid = new XidImple(new Uid());
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+        final TestSynchronization sync = new TestSynchronization();
+        t.registerSynchronization(sync);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+        final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions)xaTerminator;
+        xaTerminatorExtensions.beforeCompletion(xid);
+        assertEquals(XAResource.XA_RDONLY, xaTerminator.prepare(xid));
+        // note that unlike the above test we don't call commit - the XA_RDONLY means its finished, per XA semantics.
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, t.getStatus());
+    }
+
+    public void testTwoPhaseCommitSyncWithXAOKWithSeparateSync() throws Exception
+    {
+        final SubordinateTransaction tm = createTransaction();
+        final TestSynchronization sync = new TestSynchronization();
+        tm.registerSynchronization(sync);
+        final TestXAResource xaResource = new TestXAResource();
+        xaResource.setPrepareReturnValue(XAResource.XA_OK);
+        tm.enlistResource(xaResource);
+        tm.doBeforeCompletion();
+        assertEquals(TwoPhaseOutcome.PREPARE_OK, tm.doPrepare());
+        tm.doCommit();
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
+    }
+
+    public void testTwoPhaseCommitSyncWithXAOKViaXATerminatorWithSeparateSync() throws Exception
+    {
+        final Xid xid = new XidImple(new Uid());
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+        final TestSynchronization sync = new TestSynchronization();
+        t.registerSynchronization(sync);
+        final TestXAResource xaResource = new TestXAResource();
+        xaResource.setPrepareReturnValue(XAResource.XA_OK);
+        t.enlistResource(xaResource);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+        final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions)xaTerminator;
+        xaTerminatorExtensions.beforeCompletion(xid);
+        assertEquals(XAResource.XA_OK, xaTerminator.prepare(xid));
+        xaTerminator.commit(xid, false);
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, t.getStatus());
+    }
+
+    public void testTwoPhaseCommitSyncWithRollbackOnlyWithSeparateSync() throws Exception
+    {
+        final SubordinateTransaction tm = createTransaction();
+        final TestSynchronization sync = new TestSynchronization();
+        tm.registerSynchronization(sync);
+        tm.setRollbackOnly();
+        tm.doBeforeCompletion();
+        assertEquals(TwoPhaseOutcome.PREPARE_NOTOK, tm.doPrepare());
+        tm.doRollback();
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, tm.getStatus());
+    }
+
+    public void testTwoPhaseCommitSyncWithRollbackOnlyViaXATerminatorWithSeparateSync() throws Exception
+    {
+        final Xid xid = new XidImple(new Uid());
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+        final TestSynchronization sync = new TestSynchronization();
+        t.registerSynchronization(sync);
+        t.setRollbackOnly();
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+        final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions)xaTerminator;
+        xaTerminatorExtensions.beforeCompletion(xid);
+
+        try {
+            xaTerminator.prepare(xid);
+        } catch(XAException e) {
+            assertEquals(XAException.XA_RBROLLBACK, e.errorCode);
+            // expected - we tried to prepare a rollbackonly tx.
+        }
+        // no need to call rollback - the XA_RBROLLBACK code indicates its been done.
+        assertTrue(sync.isBeforeCompletionDone());
+        assertTrue(sync.isAfterCompletionDone());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
+    }
+
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/TestSynchronization.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/TestSynchronization.java	2009-06-05 14:40:24 UTC (rev 26855)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/TestSynchronization.java	2009-06-05 15:04:59 UTC (rev 26856)
@@ -41,11 +41,21 @@
     }
 
     public void beforeCompletion() {
+        if(beforeCompletionDone) {
+            System.out.println("beforeCompletion called more than once");
+            throw new RuntimeException("beforeCompletion called more than once");
+        }
+
         beforeCompletionDone = true;
         System.out.println("TestSynchronization.beforeCompletion()");
     }
 
     public void afterCompletion(int i) {
+        if(afterCompletionDone) {
+            System.out.println("afterCompletion called more than once");
+            throw new RuntimeException("afterCompletion called more than once");
+        }
+
         afterCompletionDone = true;
         System.out.println("TestSynchronization.afterCompletion("+i+")");
     }




More information about the jboss-svn-commits mailing list