You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/10/05 10:47:21 UTC

svn commit: r1004576 - /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java

Author: jukka
Date: Tue Oct  5 08:47:20 2010
New Revision: 1004576

URL: http://svn.apache.org/viewvc?rev=1004576&view=rev
Log:
JCR-2767: Database connection leak with DBCP, MySQL, and Observers

Patch by Christian Trimble

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java?rev=1004576&r1=1004575&r2=1004576&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java Tue Oct  5 08:47:20 2010
@@ -76,9 +76,7 @@ public class ConnectionHelper {
 
     protected final DataSource dataSource;
 
-    private boolean inBatchMode = false;
-
-    private Connection batchConnection = null;
+    private ThreadLocal<Connection> batchConnectionTl = new ThreadLocal<Connection>();
 
     /**
      * @param dataSrc the {@link DataSource} on which this instance acts
@@ -147,6 +145,15 @@ public class ConnectionHelper {
     }
 
     /**
+     * Returns true if we are currently in a batch mode, false otherwise.
+     * @return true if the current thread is running in batch mode, false otherwise.
+     */
+    protected boolean inBatchMode()
+    {
+      return batchConnectionTl.get() != null;
+    }
+
+    /**
      * The default implementation returns the {@code extraNameCharacters} provided by the databases metadata.
      * 
      * @return the additional characters for identifiers supported by the db
@@ -201,19 +208,20 @@ public class ConnectionHelper {
      * @throws SQLException on error
      */
     public final void startBatch() throws SQLException {
-        if (inBatchMode) {
+        if (inBatchMode()) {
             throw new IllegalStateException("already in batch mode");
         }
+        Connection batchConnection = null;
         try {
             batchConnection = getConnection();
             batchConnection.setAutoCommit(false);
-            inBatchMode = true;
+            batchConnectionTl.set(batchConnection);
         } catch (SQLException e) {
             // Strive for failure atomicity
             if (batchConnection != null) {
                 DbUtility.close(batchConnection, null, null);
             }
-            batchConnection = null;
+            batchConnectionTl.remove();
             throw e;
         }
     }
@@ -226,19 +234,18 @@ public class ConnectionHelper {
      *             SQLException}
      */
     public final void endBatch(boolean commit) throws SQLException {
-        if (!inBatchMode) {
+        if (!inBatchMode()) {
             throw new IllegalStateException("not in batch mode");
         }
         try {
             if (commit) {
-                batchConnection.commit();
+                batchConnectionTl.get().commit();
             } else {
-                batchConnection.rollback();
+                batchConnectionTl.get().rollback();
             }
         } finally {
-            DbUtility.close(batchConnection, null, null);
-            batchConnection = null;
-            inBatchMode = false;
+            DbUtility.close(batchConnectionTl.get(), null, null);
+            batchConnectionTl.set(null);
         }
     }
 
@@ -358,7 +365,7 @@ public class ConnectionHelper {
             if (rs == null) {
                 return null;
             }
-            if (inBatchMode) {
+            if (inBatchMode()) {
                 return ResultSetWrapper.newInstance(null, stmt, rs);
             } else {
                 return ResultSetWrapper.newInstance(con, stmt, rs);
@@ -378,8 +385,8 @@ public class ConnectionHelper {
      * @throws SQLException on error
      */
     protected final Connection getConnection() throws SQLException {
-        if (inBatchMode) {
-            return batchConnection;
+        if (inBatchMode()) {
+            return batchConnectionTl.get();
         } else {
             Connection con = dataSource.getConnection();
             // JCR-1013: Setter may fail unnecessarily on a managed connection
@@ -398,7 +405,7 @@ public class ConnectionHelper {
      * @param rs a {@code ResultSet}
      */
     protected final void closeResources(Connection con, Statement stmt, ResultSet rs) {
-        if (inBatchMode) {
+        if (inBatchMode()) {
             DbUtility.close(null, stmt, rs);
         } else {
             DbUtility.close(con, stmt, rs);
@@ -439,7 +446,7 @@ public class ConnectionHelper {
     public abstract class RetryManager<T> {
 
         public final T doTry() throws SQLException {
-            if (inBatchMode) {
+            if (inBatchMode()) {
                 return call();
             } else {
                 boolean sleepInterrupted = false;