Author: rmannibucau
Date: Thu Nov 15 13:58:48 2012
New Revision: 1409789

URL: http://svn.apache.org/viewvc?rev=1409789&view=rev
Log:
OPENEJB-1937 cleaning up transactionregistry maps

Modified:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/BasicManagedDataSource.java

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/BasicManagedDataSource.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/BasicManagedDataSource.java?rev=1409789&r1=1409788&r2=1409789&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/BasicManagedDataSource.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/BasicManagedDataSource.java
 Thu Nov 15 13:58:48 2012
@@ -16,6 +16,13 @@
  */
 package org.apache.openejb.resource.jdbc.dbcp;
 
+import org.apache.commons.dbcp.PoolingDataSource;
+import org.apache.commons.dbcp.managed.ManagedConnection;
+import org.apache.commons.dbcp.managed.ManagedDataSource;
+import org.apache.commons.dbcp.managed.TransactionRegistry;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.openejb.OpenEJB;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.resource.jdbc.BasicDataSourceUtil;
 import org.apache.openejb.resource.jdbc.IsolationLevels;
@@ -24,8 +31,11 @@ import org.apache.openejb.resource.jdbc.
 
 import javax.sql.DataSource;
 import java.io.File;
+import java.lang.reflect.Field;
+import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Logger;
@@ -236,6 +246,14 @@ public class BasicManagedDataSource exte
         }
     }
 
+    @Override
+    protected void createDataSourceInstance() {
+        final PoolingDataSource pds = new 
PatchedManagedDataSource(connectionPool, getTransactionRegistry());
+        
pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());
+        pds.setLogWriter(logWriter);
+        dataSource = pds;
+    }
+
     protected void wrapTransactionManager() {
         //TODO?
     }
@@ -279,4 +297,61 @@ public class BasicManagedDataSource exte
             l.unlock();
         }
     }
+
+    private static class PatchedManagedDataSource extends ManagedDataSource {
+        private TransactionRegistry transactionRegistry;
+
+        public PatchedManagedDataSource(final GenericObjectPool 
connectionPool, final TransactionRegistry transactionRegistry) {
+            super(connectionPool, transactionRegistry);
+            this.transactionRegistry = transactionRegistry;
+        }
+
+        @Override
+        public Connection getConnection() throws SQLException {
+            if (_pool == null) throw new IllegalStateException("Pool has not 
been set");
+            if (transactionRegistry == null) throw new 
IllegalStateException("TransactionRegistry has not been set");
+
+            return new PatchedManagedConnection(_pool, transactionRegistry, 
isAccessToUnderlyingConnectionAllowed());
+        }
+    }
+
+    private static class PatchedManagedConnection extends ManagedConnection {
+        private static final Field CACHES_FIELD;
+
+        static {
+            Field caches = null;
+            try {
+                caches = TransactionRegistry.class.getDeclaredField("caches");
+                caches.setAccessible(true);
+            } catch (NoSuchFieldException e) {
+                // no-op
+            }
+            CACHES_FIELD = caches;
+        }
+
+        private final TransactionRegistry transactionRegistry;
+
+        public PatchedManagedConnection(final ObjectPool pool, final 
TransactionRegistry transactionRegistry, final boolean 
accessToUnderlyingConnectionAllowed) throws SQLException {
+            super(pool, transactionRegistry, 
accessToUnderlyingConnectionAllowed);
+            this.transactionRegistry = transactionRegistry;
+        }
+
+        @Override
+        protected void transactionComplete() {
+            final Connection delegate = getDelegateInternal();
+            try {
+                super.transactionComplete();
+            } finally { // clean up transaction registry
+                transactionRegistry.unregisterConnection(delegate);
+                if (CACHES_FIELD != null) {
+                    try {
+                        final Map<?, ?> caches = (Map<?, ?>) 
CACHES_FIELD.get(transactionRegistry);
+                        
caches.remove(OpenEJB.getTransactionManager().getTransaction());
+                    } catch (Exception e) {
+                        // no-op
+                    }
+                }
+            }
+        }
+    }
 }


Reply via email to