[jboss-cvs] JBossAS SVN: r79140 - branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Oct 6 07:21:55 EDT 2008


Author: jesper.pedersen
Date: 2008-10-06 07:21:55 -0400 (Mon, 06 Oct 2008)
New Revision: 79140

Modified:
   branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/BaseConnectionManager2.java
   branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/NoTxConnectionManager.java
   branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/TxConnectionManager.java
Log:
[JBPAPP-1252] Race condition between connection.close() and transaction.rollback()

Modified: branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/BaseConnectionManager2.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/BaseConnectionManager2.java	2008-10-06 11:08:10 UTC (rev 79139)
+++ branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/BaseConnectionManager2.java	2008-10-06 11:21:55 UTC (rev 79140)
@@ -34,6 +34,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.management.MBeanNotificationInfo;
 import javax.management.MBeanServer;
@@ -506,7 +507,7 @@
    //does NOT put the mc back in the pool if no more handles. Doing so would introduce a race condition
    //whereby the mc got back in the pool while still enlisted in the tx.
    //The mc could be checked out again and used before the delist occured.
-   protected void unregisterAssociation(ConnectionListener cl, Object c) throws ResourceException
+   protected void unregisterAssociation(ConnectionListener cl, Object c)
    {
       cl.unregisterConnection(c);
    }
@@ -627,7 +628,7 @@
 
       private long lastUse;
 
-      private boolean trackByTx = false;
+      private AtomicBoolean trackByTx = new AtomicBoolean(false);
 
       private boolean permit = false;
 
@@ -685,12 +686,12 @@
 
       public boolean isTrackByTx()
       {
-         return trackByTx;
+         return trackByTx.get();
       }
 
       public void setTrackByTx(boolean trackByTx)
       {
-         this.trackByTx = trackByTx;
+         this.trackByTx.set(trackByTx);
       }
 
       public void tidyup() throws ResourceException
@@ -808,7 +809,7 @@
          buffer.append(" handles=").append(handles.size());
          buffer.append(" lastUse=").append(lastUse);
          buffer.append(" permit=").append(permit);
-         buffer.append(" trackByTx=").append(trackByTx);
+         buffer.append(" trackByTx=").append(trackByTx.get());
          buffer.append(" mcp=").append(mcp);
          buffer.append(" context=").append(context);
          toString(buffer);

Modified: branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/NoTxConnectionManager.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/NoTxConnectionManager.java	2008-10-06 11:08:10 UTC (rev 79139)
+++ branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/NoTxConnectionManager.java	2008-10-06 11:21:55 UTC (rev 79140)
@@ -91,18 +91,12 @@
          {
             log.info("Throwable from unregisterConnection", t);
          }
-         try
+
+         unregisterAssociation(this, ce.getConnectionHandle());
+         if (isManagedConnectionFree())
          {
-            unregisterAssociation(this, ce.getConnectionHandle());
-            if (isManagedConnectionFree())
-            {
-               returnManagedConnection(this, false);
-            }
+            returnManagedConnection(this, false);
          }
-         catch (ResourceException re)
-         {
-            log.error("ResourceException while closing connection handle!", re);
-         }
       }
 
       public void localTransactionStarted(ConnectionEvent ce)

Modified: branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/TxConnectionManager.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/TxConnectionManager.java	2008-10-06 11:08:10 UTC (rev 79139)
+++ branches/JBPAPP_4_2_0_GA_CP/connector/src/main/org/jboss/resource/connectionmanager/TxConnectionManager.java	2008-10-06 11:21:55 UTC (rev 79140)
@@ -372,11 +372,16 @@
       }
 
       //if there are no more handles and tx is complete, we can return to pool.
-      boolean isFree = cl.isManagedConnectionFree();
-      if (trace)
-         log.trace("Disconnected isManagedConnectionFree=" + isFree + " cl=" + cl);
-      if (isFree)
+      if (cl.isManagedConnectionFree())
+      {
+         if (trace)
+            log.trace("Disconnected isManagedConnectionFree=true" + " cl=" + cl);
          returnManagedConnection(cl, false);
+      }
+      else if (trace)
+      {
+         log.trace("Disconnected isManagedConnectionFree=false" + " cl=" + cl);
+      }
 
       // Rethrow the error
       if (throwable != null)
@@ -643,16 +648,18 @@
 
          try
          {
-            unregisterAssociation(this, ce.getConnectionHandle());
-            boolean isFree = isManagedConnectionFree();
-            if (trace)
-               log.trace("isManagedConnectionFree=" + isFree + " mc=" + this.getManagedConnection());
-            //no more handles
-            if (isFree)
+            if (wasFreed(ce.getConnectionHandle()))
             {
                delist();
+               if (trace)
+                  log.trace("isManagedConnectionFree=true mc=" + this.getManagedConnection());
                returnManagedConnection(this, false);
             }
+            else
+            {
+               if (trace)
+                  log.trace("isManagedConnectionFree=false mc=" + this.getManagedConnection());
+            }
          }
          catch (Throwable t)
          {
@@ -715,6 +722,41 @@
          return super.isManagedConnectionFree();
       }
 
+      /**
+       * This method changes the number of handles or 
+       * the track-by-tx value depending on the parameter passed in
+       * @param handle The handle; if <code>null</code> track-by-tx is changed
+       * @return True if the managed connection was freed
+       */
+      synchronized boolean wasFreed(Object handle)
+      {
+         if (handle != null)
+         {
+            if (isManagedConnectionFree())
+            {
+               // This shouldn't really happen now all the state is changed atomically
+               return false;
+            }
+	
+            // Change the number of handles
+            unregisterAssociation(this, handle);
+         }
+         else
+         {
+            if (!isTrackByTx())
+            {
+               // Only change the state once
+               return false;
+            }
+	
+            // Set track-by-tx to false
+            setTrackByTx(false);
+         }
+	         
+         // Return if the managed connection was just freed
+         return isManagedConnectionFree();
+      }
+
       private class TransactionSynchronization implements Synchronization
       {
          /** Transaction */
@@ -840,8 +882,10 @@
             // This is where we close when doing track by transaction
             if (wasTrackByTx)
             {
-               setTrackByTx(false);
-               if (isManagedConnectionFree())
+               if (trace)
+                  log.trace("afterCompletion(" + status + ") isTrackByTx=" + isTrackByTx() + " for " + TxConnectionEventListener.this);
+
+               if (wasFreed(null))
                   returnManagedConnection(TxConnectionEventListener.this, false);
             }
          }




More information about the jboss-cvs-commits mailing list