You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2006/11/16 22:48:09 UTC
svn commit: r475936 - in
/geronimo/server/trunk/modules/geronimo-connector/src/main/java/org/apache/geronimo/connector:
./ outbound/ outbound/connectiontracking/
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();