geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r475936 - in /geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector: ./ outbound/ outbound/connectiontracking/
Date Thu, 16 Nov 2006 21:48:09 GMT
Author: djencks
Date: Thu Nov 16 13:48:08 2006
New Revision: 475936

URL: http://svn.apache.org/viewvc?view=rev&rev=475936
Log:
GERONIMO-2573 Be more careful about registering Synchronization with non-active tx. Also add
a lot of trace level logging to help with the next connection leak.

Modified:
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/ConnectorTransactionContext.java
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GeronimoConnectionEventListener.java
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
    geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinator.java

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/ConnectorTransactionContext.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/ConnectorTransactionContext.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/ConnectorTransactionContext.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/ConnectorTransactionContext.java
Thu Nov 16 13:48:08 2006
@@ -25,6 +25,7 @@
 import javax.transaction.Synchronization;
 import javax.transaction.RollbackException;
 import javax.transaction.SystemException;
+import javax.transaction.Status;
 
 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
 import org.apache.geronimo.connector.outbound.TransactionCachingInterceptor;
@@ -45,18 +46,20 @@
             ctx = new ConnectorTransactionContext();
 
             try {
-                transaction.registerSynchronization(new ConnectorSynchronization(ctx, transaction));
+                if (transaction.getStatus() == Status.STATUS_ACTIVE) {
+                    transaction.registerSynchronization(new ConnectorSynchronization(ctx,
transaction));
+                    // Note: no synchronization is necessary here.  Since a transaction can
only be associated with a single
+                    // thread at a time, it should not be possible for someone else to have
snuck in and created a
+                    // ConnectorTransactionContext for this transaction.  We still protect
against that with the putIfAbsent
+                    // call below, and we simply have an extra transaction synchronization
registered that won't do anything
+                    DATA_INDEX.putIfAbsent(transaction, ctx);
+                }
             } catch (RollbackException e) {
                 throw (IllegalStateException) new IllegalStateException("Transaction is already
rolled back").initCause(e);
             } catch (SystemException e) {
                 throw new RuntimeException("Unable to register ejb transaction synchronization
callback", e);
             }
 
-            // Note: no synchronization is necessary here.  Since a transaction can only
be associated with a single
-            // thread at a time, it should not be possible for someone else to have snuck
in and created a
-            // ConnectorTransactionContext for this transaction.  We still protect against
that with the putIfAbsent
-            // call below, and we simply have an extra transaction synchronization registered
that won't do anything
-            DATA_INDEX.putIfAbsent(transaction, ctx);
         }
         return ctx;
     }

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
Thu Nov 16 13:48:08 2006
@@ -38,7 +38,7 @@
  * @version $Rev$ $Date$
  */
 public abstract class AbstractSinglePoolConnectionInterceptor implements ConnectionInterceptor,
PoolingAttributes {
-    protected static Log log = LogFactory.getLog(SinglePoolConnectionInterceptor.class.getName());
+    protected static Log log = LogFactory.getLog(AbstractSinglePoolConnectionInterceptor.class.getName());
     protected final ConnectionInterceptor next;
     private final ReadWriteLock resizeLock = new ReentrantReadWriteLock();
     protected Semaphore permits;
@@ -67,6 +67,9 @@
 
     public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
         if (connectionInfo.getManagedConnectionInfo().getManagedConnection() != null) {
+            if (log.isTraceEnabled()) {
+                log.trace("using already assigned connection " + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to pool " + this);
+            }
             return;
         }
         try {
@@ -78,7 +81,7 @@
                     throw new ResourceException("No ManagedConnections available "
                             + "within configured blocking timeout ( "
                             + blockingTimeoutMilliseconds
-                            + " [ms] )");
+                            + " [ms] ) for pool " + this);
 
                 }
             } finally {
@@ -95,7 +98,7 @@
     public void returnConnection(ConnectionInfo connectionInfo,
                                  ConnectionReturnAction connectionReturnAction) {
         if (log.isTraceEnabled()) {
-            log.trace("returning connection" + connectionInfo.getConnectionHandle());
+            log.trace("returning connection " + connectionInfo.getConnectionHandle() + "
for MCI " + connectionInfo.getManagedConnectionInfo() + " and MC " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to pool " + this);
         }
 
         // not strictly synchronized with destroy(), but pooled operations in internalReturn()
are...
@@ -112,6 +115,9 @@
         try {
             ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
             if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE &&
mci.hasConnectionHandles()) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Return request at pool with connection handles! " + connectionInfo.getConnectionHandle()
+ " for MCI " + connectionInfo.getManagedConnectionInfo() + " and MC " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to pool " + this, new Exception("Stack trace"));
+                }
                 return;
             }
 

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
Thu Nov 16 13:48:08 2006
@@ -23,6 +23,8 @@
 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.TransactionSupport;
 import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTracker;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * GenericConnectionManager sets up a connection manager stack according to the
@@ -31,6 +33,7 @@
  * @version $Rev$ $Date$
  */
 public class GenericConnectionManager extends AbstractConnectionManager {
+    protected static final Log log = LogFactory.getLog(AbstractSinglePoolConnectionInterceptor.class.getName());
 
     //default constructor for use as endpoint
     public GenericConnectionManager() {
@@ -84,6 +87,10 @@
 
             stack = transactionSupport.addXAResourceInsertionInterceptor(stack, objectName);
             stack = pooling.addPoolingInterceptors(stack);
+            if (log.isTraceEnabled()) {
+                log.trace("Connection Manager " + objectName + " installed pool " + stack);
+            }
+
             this.poolingSupport = pooling;
             stack = transactionSupport.addTransactionInterceptors(stack, transactionManager);
 

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GeronimoConnectionEventListener.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GeronimoConnectionEventListener.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GeronimoConnectionEventListener.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/GeronimoConnectionEventListener.java
Thu Nov 16 13:48:08 2006
@@ -60,11 +60,20 @@
                     + connectionEvent.getSource());
         }
         if (log.isTraceEnabled()) {
-            log.trace("connectionClosed called with " + connectionEvent.getConnectionHandle());
+            log.trace("connectionClosed called with " + connectionEvent.getConnectionHandle()
+ " for MCI: " + managedConnectionInfo + " and MC: " + managedConnectionInfo.getManagedConnection());
         }
         ConnectionInfo ci = new ConnectionInfo(managedConnectionInfo);
         ci.setConnectionHandle(connectionEvent.getConnectionHandle());
-        stack.returnConnection(ci, ConnectionReturnAction.RETURN_HANDLE);
+        try {
+            stack.returnConnection(ci, ConnectionReturnAction.RETURN_HANDLE);
+        } catch (Throwable e) {
+            if (log.isTraceEnabled()) {
+                log.trace("connectionClosed failed with " + connectionEvent.getConnectionHandle()
+ " for MCI: " + managedConnectionInfo + " and MC: " + managedConnectionInfo.getManagedConnection(),
e);
+            }
+            if (e instanceof Error) {
+                throw (Error)e;
+            }
+        }
     }
 
     public void connectionErrorOccurred(ConnectionEvent connectionEvent) {

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
Thu Nov 16 13:48:08 2006
@@ -23,6 +23,9 @@
 import javax.resource.ResourceException;
 import javax.resource.spi.ManagedConnection;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 /**
  * SinglePoolConnectionInterceptor chooses a single connection from the pool.  If selectOneAssumeMatch
  * is true, it simply returns the selected connection.
@@ -35,7 +38,7 @@
  * @version $Rev$ $Date$
  */
 public class SinglePoolConnectionInterceptor extends AbstractSinglePoolConnectionInterceptor
{
-
+    private static final Log log = LogFactory.getLog(SinglePoolConnectionInterceptor.class.getName());
 
     private boolean selectOneAssumeMatch;
 
@@ -57,13 +60,13 @@
             if (destroyed) {
                 throw new ResourceException("ManagedConnection pool has been destroyed");
             }
-                
+
             ManagedConnectionInfo newMCI = null;
             if (pool.isEmpty()) {
                 next.getConnection(connectionInfo);
                 connectionCount++;
                 if (log.isTraceEnabled()) {
-                    log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
+                    log.trace("Supplying new connection MCI: " + connectionInfo.getManagedConnectionInfo()
+ " MC: " + connectionInfo.getManagedConnectionInfo().getManagedConnection() + " from pool:
" + this);
                 }
                 return;
             } else {
@@ -75,7 +78,7 @@
             if (selectOneAssumeMatch) {
                 connectionInfo.setManagedConnectionInfo(newMCI);
                 if (log.isTraceEnabled()) {
-                    log.trace("Returning pooled connection without checking matching " +
connectionInfo.getManagedConnectionInfo());
+                    log.trace("Supplying pooled connection without checking matching MCI:
" + connectionInfo.getManagedConnectionInfo() + " MC: " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " from pool: " + this);
                 }
                 return;
             }
@@ -90,7 +93,7 @@
                 if (matchedMC != null) {
                     connectionInfo.setManagedConnectionInfo(newMCI);
                     if (log.isTraceEnabled()) {
-                        log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
+                        log.trace("Supplying pooled connection  MCI: " + connectionInfo.getManagedConnectionInfo()
+ " MC: " + connectionInfo.getManagedConnectionInfo().getManagedConnection() + " from pool:
" + this);
                     }
                     return;
                 } else {
@@ -145,7 +148,7 @@
                 catch (ResourceException re) { } // ignore
                 return pool.remove(mci);
             }
-                
+
             if (shrinkLater > 0) {
                 //nothing can get in the pool while shrinkLater > 0, so wasInPool is false
here.
                 connectionReturnAction = ConnectionReturnAction.DESTROY;

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
Thu Nov 16 13:48:08 2006
@@ -29,6 +29,8 @@
 
 import org.apache.geronimo.connector.ConnectorTransactionContext;
 import org.apache.geronimo.connector.ConnectionReleaser;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * TransactionCachingInterceptor.java
@@ -51,6 +53,7 @@
  * @version 1.0
  */
 public class TransactionCachingInterceptor implements ConnectionInterceptor, ConnectionReleaser
{
+    protected static Log log = LogFactory.getLog(TransactionCachingInterceptor.class.getName());
 
     private final ConnectionInterceptor next;
     private final TransactionManager transactionManager;
@@ -78,9 +81,15 @@
                 if (managedConnectionInfo != null) {
                     connectionInfo.setManagedConnectionInfo(managedConnectionInfo);
                     //return;
+                    if (log.isTraceEnabled()) {
+                        log.trace("supplying connection from tx cache " + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+                    }
                 } else {
                     next.getConnection(connectionInfo);
                     managedConnectionInfos.setShared(connectionInfo.getManagedConnectionInfo());
+                    if (log.isTraceEnabled()) {
+                        log.trace("supplying connection from pool " + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+                    }
                 }
             }
         } else {
@@ -91,6 +100,9 @@
     public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction)
{
 
         if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
+            if (log.isTraceEnabled()) {
+                log.trace("destroying connection" + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+            }
             next.returnConnection(connectionInfo, connectionReturnAction);
             return;
         }
@@ -99,25 +111,40 @@
             transaction = transactionManager.getTransaction();
             if (transaction != null) {
                 if (TxUtil.isActive(transaction)) {
+                    if (log.isTraceEnabled()) {
+                        log.trace("tx active, not returning connection" + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+                    }
                     return;
                 }
                 //We are called from an afterCompletion synchronization.  Remove the MCI
from the ManagedConnectionInfos
                 //so we don't close it twice
                 ManagedConnectionInfos managedConnectionInfos = ConnectorTransactionContext.get(transaction,
this);
                 managedConnectionInfos.remove(connectionInfo.getManagedConnectionInfo());
+                if (log.isTraceEnabled()) {
+                    log.trace("tx ended, but not removed");
+                }
             }
         } catch (SystemException e) {
             //ignore
         }
+        if (log.isTraceEnabled()) {
+            log.trace("tx ended, returning connection" + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+        }
         internalReturn(connectionInfo, connectionReturnAction);
     }
 
     private void internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction)
{
         if (connectionInfo.getManagedConnectionInfo().hasConnectionHandles()) {
+            if (log.isTraceEnabled()) {
+                log.trace("not returning connection from tx cache (has handles) " + connectionInfo.getConnectionHandle()
+ " for managed connection " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+            }
             return;
         }
         //No transaction, no handles, we return it.
         next.returnConnection(connectionInfo, connectionReturnAction);
+        if (log.isTraceEnabled()) {
+            log.trace("completed return of connection through tx cache " + connectionInfo.getConnectionHandle()
+ " for MCI: " + connectionInfo.getManagedConnectionInfo() + " and MC " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " to tx caching interceptor " + this);
+        }
     }
 
     public void destroy() {
@@ -128,10 +155,16 @@
         ManagedConnectionInfos managedConnectionInfos = (ManagedConnectionInfos) stuff;
         ManagedConnectionInfo sharedMCI = managedConnectionInfos.getShared();
         if (sharedMCI != null) {
+            if (log.isTraceEnabled()) {
+                log.trace("Transaction completed, attempting to return shared connection
MCI: " + sharedMCI + " for managed connection " + sharedMCI.getManagedConnection() + " to
tx caching interceptor " + this);
+            }
             returnHandle(sharedMCI);
         }
         for (Iterator iterator = managedConnectionInfos.getUnshared().iterator(); iterator.hasNext();)
{
             ManagedConnectionInfo managedConnectionInfo = (ManagedConnectionInfo) iterator.next();
+            if (log.isTraceEnabled()) {
+                log.trace("Transaction completed, attempting to return unshared connection
MCI: " + managedConnectionInfo + " for managed connection " + managedConnectionInfo.getManagedConnection()
+ " to tx caching interceptor " + this);
+            }
             returnHandle(managedConnectionInfo);
         }
     }

Modified: geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinator.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinator.java?view=diff&rev=475936&r1=475935&r2=475936
==============================================================================
--- geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinator.java
(original)
+++ geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinator.java
Thu Nov 16 13:48:08 2006
@@ -27,6 +27,8 @@
 import org.apache.geronimo.connector.outbound.ConnectionInfo;
 import org.apache.geronimo.connector.outbound.ConnectionTrackingInterceptor;
 import org.apache.geronimo.connector.outbound.ManagedConnectionInfo;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * ConnectionTrackingCoordinator tracks connections that are in use by
@@ -45,6 +47,7 @@
  * @version $Rev$ $Date$
  */
 public class ConnectionTrackingCoordinator implements TrackedConnectionAssociator, ConnectionTracker
{
+    private static final Log log = LogFactory.getLog(ConnectionTrackingCoordinator.class.getName());
 
     private final ThreadLocal currentInstanceContexts = new ThreadLocal();
 
@@ -118,6 +121,11 @@
         }
         Map resources = connectorInstanceContext.getConnectionManagerMap();
         Set infos = (Set) resources.get(connectionTrackingInterceptor);
+        if (infos == null) {
+            if (log.isTraceEnabled()) {
+                log.trace("No infos found for handle " + connectionInfo.getConnectionHandle()
+ " for MCI: " + connectionInfo.getManagedConnectionInfo() + " for MC: " + connectionInfo.getManagedConnectionInfo().getManagedConnection()
+ " for CTI: " + connectionTrackingInterceptor, new Exception("Stack Trace"));
+            }
+        }
         if (connectionInfo.getConnectionHandle() == null) {
             //destroy was called as a result of an error
             ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();



Mime
View raw message