You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by km...@apache.org on 2013/08/12 20:23:40 UTC

svn commit: r1513218 - /db/derby/code/trunk/java/client/org/apache/derby/client/am/LogicalConnection.java

Author: kmarsden
Date: Mon Aug 12 18:23:39 2013
New Revision: 1513218

URL: http://svn.apache.org/r1513218
Log:
DERBY-5560 Java deadlock between LogicalConnection40 and ClientXAConnection40

Patch contributed by Brett Bergquist


Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/LogicalConnection.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/LogicalConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/LogicalConnection.java?rev=1513218&r1=1513217&r2=1513218&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/LogicalConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/LogicalConnection.java Mon Aug 12 18:23:39 2013
@@ -96,36 +96,41 @@ public class LogicalConnection implement
     // ------------------------ logical connection close -------------------------
     // All methods are simply forwarded to the physical connection, except for close() and isClosed().
 
-    synchronized public void close() throws SQLException {
-        try
-        {
-            // we also need to loop thru all the logicalStatements and close them
-            if (physicalConnection_ == null) {
-                return;
-            }
-            if (physicalConnection_.agent_.loggingEnabled()) {
-                physicalConnection_.agent_.logWriter_.traceEntry(this, "close");
-            }
-
-            if (physicalConnection_.isClosed()) // connection is closed or has become stale
-            {
-                pooledConnection_.informListeners(new SqlException(null, 
-                    new ClientMessageId(
-                        SQLState.PHYSICAL_CONNECTION_ALREADY_CLOSED)));
-            } else {
-                physicalConnection_.checkForTransactionInProgress();
-                physicalConnection_.closeForReuse(
-                        pooledConnection_.isStatementPoolingEnabled());
-                if (!physicalConnection_.isGlobalPending_()) {
-                    pooledConnection_.recycleConnection();
+    public void close() throws SQLException {
+        // The pooledConnection owns this LogicalConnection.  To ensure that
+        //  there is no deadlock when calling back into the pooledConnection_.recycleConnection
+        //  below, we first synchronize on the pooledConnection and then on this
+        //  LogicalConnection
+        synchronized (pooledConnection_) {
+            synchronized (this) {
+                try {
+                    // we also need to loop thru all the logicalStatements and close them
+                    if (physicalConnection_ == null) {
+                        return;
+                    }
+                    if (physicalConnection_.agent_.loggingEnabled()) {
+                        physicalConnection_.agent_.logWriter_.traceEntry(this, "close");
+                    }
+
+                    if (physicalConnection_.isClosed()) // connection is closed or has become stale
+                    {
+                        pooledConnection_.informListeners(new SqlException(null,
+                                new ClientMessageId(
+                                SQLState.PHYSICAL_CONNECTION_ALREADY_CLOSED)));
+                    } else {
+                        physicalConnection_.checkForTransactionInProgress();
+                        physicalConnection_.closeForReuse(
+                                pooledConnection_.isStatementPoolingEnabled());
+                        if (!physicalConnection_.isGlobalPending_()) {
+                            pooledConnection_.recycleConnection();
+                        }
+                    }
+                    physicalConnection_ = null;
+                    pooledConnection_.nullLogicalConnection();
+                } catch (SqlException se) {
+                    throw se.getSQLException();
                 }
             }
-            physicalConnection_ = null;
-            pooledConnection_.nullLogicalConnection();
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
         }
     }