[jboss-cvs] JBoss Messaging SVN: r5754 - in branches/Branch_1_4: tests/src/org/jboss/test/messaging/jms and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Jan 28 10:41:00 EST 2009


Author: jmesnil
Date: 2009-01-28 10:41:00 -0500 (Wed, 28 Jan 2009)
New Revision: 5754

Modified:
   branches/Branch_1_4/src/main/org/jboss/jms/tx/MessagingXAResource.java
   branches/Branch_1_4/src/main/org/jboss/jms/tx/ResourceManager.java
   branches/Branch_1_4/tests/src/org/jboss/test/messaging/jms/XATest.java
Log:
JBMESSAGING-1493: MessagingXAResource.isSameRM does not work after closing a connection

* comparing the ResourceManager's serverID is not enough to ensure the resource manager is the same.
For example suppose a resource is enlisted on a connection and this connection is closed. Since no work has been done on the tx, it is forgotten.
Then another connection is created and a resource is enlisted, the resource manager will be have the same serverID (the new connection points to the same server) but the resource manager won't know about the xid.
To fix it, we check in MessagingXAResource.isSameRM that both ResourceManager have the same serverID *and* the same map of transactions.
This way, if a resource manager ever returns true, the subsequent call to start(TMJOIN) will succeed

* one thing to note, in that case, the transaction will rollback at completion time (because the 1st resource will not be delisted properly, it no longer exists) and any message delivered in the tx will be redelivered


Modified: branches/Branch_1_4/src/main/org/jboss/jms/tx/MessagingXAResource.java
===================================================================
--- branches/Branch_1_4/src/main/org/jboss/jms/tx/MessagingXAResource.java	2009-01-28 15:26:50 UTC (rev 5753)
+++ branches/Branch_1_4/src/main/org/jboss/jms/tx/MessagingXAResource.java	2009-01-28 15:41:00 UTC (rev 5754)
@@ -109,7 +109,8 @@
          return false;
       }
       
-      boolean same = ((MessagingXAResource)xaResource).rm.getServerID() == this.rm.getServerID();
+      boolean same = (((MessagingXAResource)xaResource).rm.getServerID() == this.rm.getServerID())
+                  && (((MessagingXAResource)xaResource).rm.getTransactions() == this.rm.getTransactions());
       
       if (trace) { log.trace("Calling isSameRM, result is " + same + " " + ((MessagingXAResource)xaResource).rm.getServerID() + " " + this.rm.getServerID()); }
             

Modified: branches/Branch_1_4/src/main/org/jboss/jms/tx/ResourceManager.java
===================================================================
--- branches/Branch_1_4/src/main/org/jboss/jms/tx/ResourceManager.java	2009-01-28 15:26:50 UTC (rev 5753)
+++ branches/Branch_1_4/src/main/org/jboss/jms/tx/ResourceManager.java	2009-01-28 15:41:00 UTC (rev 5754)
@@ -602,7 +602,12 @@
          return new Xid[0];
       }
    }
-   
+
+   Map getTransactions()
+   {
+      return transactions;
+   }
+
    // Private --------------------------------------------------------------------------------------
    
    private ClientTransaction getTxInternal(Object xid)

Modified: branches/Branch_1_4/tests/src/org/jboss/test/messaging/jms/XATest.java
===================================================================
--- branches/Branch_1_4/tests/src/org/jboss/test/messaging/jms/XATest.java	2009-01-28 15:26:50 UTC (rev 5753)
+++ branches/Branch_1_4/tests/src/org/jboss/test/messaging/jms/XATest.java	2009-01-28 15:41:00 UTC (rev 5754)
@@ -39,6 +39,7 @@
 import javax.jms.XASession;
 import javax.management.ObjectName;
 import javax.naming.InitialContext;
+import javax.transaction.RollbackException;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
 import javax.transaction.xa.XAException;
@@ -366,6 +367,61 @@
 
    }
 
+   public void testTransactionRollbackAfterClosingAConnectionWithEnlistedResource() throws Exception
+   {
+      XAConnection conn = null;
+      XAConnection conn2 = null;
+
+      try
+      {
+
+         conn = cf.createXAConnection();
+
+         // Create a session
+         XASession sess1 = conn.createXASession();
+         XAResource res1 = (XAResource)sess1.getXAResource();
+         
+         tm.begin();
+         
+         Transaction transaction = tm.getTransaction();
+         transaction.enlistResource(res1);
+                  
+         // a remoting exception occurs -> we close the connection         
+         conn.close();
+         // and we create a new one
+         conn2 = cf.createXAConnection();
+
+         XASession sess2 = conn2.createXASession();
+         XAResource res2 = (XAResource)sess2.getXAResource();
+         
+         assertFalse(res2.isSameRM(res1));
+         transaction.enlistResource(res2);
+
+         assertFalse(transaction.delistResource(res1, XAResource.TMSUCCESS));
+         assertTrue(transaction.delistResource(res2, XAResource.TMSUCCESS));
+         
+         try {
+            transaction.commit();
+            fail("transaction must roll back since res1 was not properly delisted");
+         } 
+         catch (RollbackException e)
+         {
+         }
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            conn.close();
+         }
+         if (conn2 != null)
+         {
+            conn2.close();
+         }
+
+      }
+   }
+   
    // http://jira.jboss.com/jira/browse/JBMESSAGING-1221
    public void testMemoryLeakForLocalTXsOnResumeOnePhase() throws Exception
    {




More information about the jboss-cvs-commits mailing list