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();
}
}