Repository: cayenne
Updated Branches:
  refs/heads/master 30e892c68 -> 99b282838


CAY-2009 Non-blocking connection pool

* ensure consistent auto-commit state
  (this was the real cause of H2 failures)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/e784c105
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/e784c105
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/e784c105

Branch: refs/heads/master
Commit: e784c10537e0d268fe9d41e3bbd62a2d2ec1301a
Parents: 30e892c
Author: aadamchik <[email protected]>
Authored: Sun May 3 07:24:54 2015 -0400
Committer: aadamchik <[email protected]>
Committed: Sun May 3 07:27:41 2015 -0400

----------------------------------------------------------------------
 .../cayenne/datasource/PoolAwareConnection.java | 24 ++---------
 .../cayenne/datasource/PoolingDataSource.java   | 42 +++++++++++++++++++-
 .../cayenne/datasource/PoolingDataSourceIT.java | 12 ++++++
 3 files changed, 57 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/e784c105/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolAwareConnection.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolAwareConnection.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolAwareConnection.java
index 6b90504..da1e3d9 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolAwareConnection.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolAwareConnection.java
@@ -51,24 +51,7 @@ public class PoolAwareConnection implements Connection {
        private Connection connection;
        private String validationQuery;
 
-       // An old hack that fixes Sybase problems with autocommit. Used idea 
from
-       // Jonas org.objectweb.jonas.jdbc_xa.ConnectionImpl
-       // (http://www.objectweb.org/jonas/).
-       //
-       // If problem is not the one that can be fixed by this patch, original
-       // exception is rethrown. If exception occurs when fixing the problem, 
new
-       // exception is thrown.
-       //
-       static void sybaseAutoCommitPatch(Connection c, SQLException e, boolean 
autoCommit) throws SQLException {
-
-               String s = e.getMessage().toLowerCase();
-               if (s.contains("set chained command not allowed")) {
-                       c.commit();
-                       c.setAutoCommit(autoCommit); // Shouldn't fail now.
-               } else {
-                       throw e;
-               }
-       }
+       
 
        public PoolAwareConnection(PoolingDataSource parent, Connection 
connection, String validationQuery) {
                this.parent = parent;
@@ -118,6 +101,8 @@ public class PoolAwareConnection implements Connection {
                        // state
                }
 
+               // TODO: autocommit, tx isolation, and other connection 
settings may
+               // change when resetting connection and need to be restored...
                try {
                        connection = parent.createUnwrapped();
                } catch (SQLException e) {
@@ -312,8 +297,7 @@ public class PoolAwareConnection implements Connection {
                } catch (SQLException sqlEx) {
 
                        try {
-                               // apply Sybase patch
-                               sybaseAutoCommitPatch(connection, sqlEx, 
autoCommit);
+                               
PoolingDataSource.sybaseAutoCommitPatch(connection, sqlEx, autoCommit);
                        } catch (SQLException patchEx) {
                                parent.retire(this);
                                throw sqlEx;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e784c105/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolingDataSource.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolingDataSource.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolingDataSource.java
index 83bf2f2..bb7f732 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolingDataSource.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/PoolingDataSource.java
@@ -44,6 +44,26 @@ import org.apache.commons.logging.LogFactory;
  */
 public class PoolingDataSource implements DataSource {
 
+       // An old hack that fixes Sybase problems with autocommit. Used idea 
from
+       // Jonas org.objectweb.jonas.jdbc_xa.ConnectionImpl
+       // (http://www.objectweb.org/jonas/).
+       //
+       // If problem is not the one that can be fixed by this patch, original
+       // exception is rethrown. If exception occurs when fixing the problem, 
new
+       // exception is thrown.
+       //
+       static void sybaseAutoCommitPatch(Connection c, SQLException e, boolean 
autoCommit) throws SQLException {
+
+               String s = e.getMessage().toLowerCase();
+               if (s.contains("set chained command not allowed")) {
+                       // TODO: the hack is ugly... should we rollback instead 
here?
+                       c.commit();
+                       c.setAutoCommit(autoCommit); // Shouldn't fail now.
+               } else {
+                       throw e;
+               }
+       }
+
        /**
         * Defines a maximum time in milliseconds that a connection request 
could
         * wait in the connection queue. After this period expires, an exception
@@ -238,8 +258,28 @@ public class PoolingDataSource implements DataSource {
                return new PoolAwareConnection(this, createUnwrapped(), 
validationQuery);
        }
 
+       /**
+        * Creates a new connection in a consistent state.
+        */
        Connection createUnwrapped() throws SQLException {
-               return nonPoolingDataSource.getConnection();
+               Connection c = nonPoolingDataSource.getConnection();
+
+               // set default connection state...
+
+               // TODO: tx isolation level?
+
+               if (!c.getAutoCommit()) {
+
+                       try {
+                               c.setAutoCommit(true);
+                       } catch (SQLException e) {
+                               PoolingDataSource.sybaseAutoCommitPatch(c, e, 
true);
+                       }
+               }
+
+               c.clearWarnings();
+
+               return c;
        }
 
        @Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e784c105/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSourceIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSourceIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSourceIT.java
index e9b0746..7052281 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSourceIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSourceIT.java
@@ -20,6 +20,7 @@
 package org.apache.cayenne.datasource;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.sql.Connection;
@@ -44,6 +45,17 @@ public class PoolingDataSourceIT extends 
BasePoolingDataSourceIT {
        }
 
        @Test
+       public void testGetConnectionAutoCommit() throws Exception {
+
+               Connection c1 = dataSource.getConnection();
+               try {
+                       assertTrue("Failed to reset connection state", 
c1.getAutoCommit());
+               } finally {
+                       c1.close();
+               }
+       }
+
+       @Test
        public void testGetConnection() throws Exception {
 
                assertEquals(2, dataSource.poolSize());

Reply via email to