[libpostgresql-jdbc-java] 06/13: The previous patch to try and set a XA based Connection's autocommit property correctly didn't quite work. Calling XAConnection.getConnection set autocommit to true even if we already had a transaction in progress.

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Mon Jan 9 10:20:03 UTC 2017


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to tag REL8_1_410
in repository libpostgresql-jdbc-java.

commit 38e52a6c51b8812575ad4220b813cc5e01c76f1a
Author: Kris Jurka <books at ejurka.com>
Date:   Fri Jul 6 20:32:55 2007 +0000

    The previous patch to try and set a XA based Connection's autocommit
    property correctly didn't quite work.  Calling
    XAConnection.getConnection set autocommit to true even if we already
    had a transaction in progress.
    
    Reported by Luca Ferrari
    Fixed by Heikki Linnakangas
---
 org/postgresql/test/xa/XADataSourceTest.java | 19 +++++++++++++++
 org/postgresql/xa/PGXAConnection.java        | 36 +++++++++++++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/org/postgresql/test/xa/XADataSourceTest.java b/org/postgresql/test/xa/XADataSourceTest.java
index ba2a4ca..0f2021c 100644
--- a/org/postgresql/test/xa/XADataSourceTest.java
+++ b/org/postgresql/test/xa/XADataSourceTest.java
@@ -220,8 +220,11 @@ public class XADataSourceTest extends TestCase {
     public void testAutoCommit() throws Exception {
         Xid xid = new CustomXid(6);
 
+        // When not in an XA transaction, autocommit should be true
+        // per normal JDBC rules.
         assertTrue(conn.getAutoCommit());
 
+        // When in an XA transaction, autocommit should be false
         xaRes.start(xid, XAResource.TMNOFLAGS);
         assertFalse(conn.getAutoCommit());
         xaRes.end(xid, XAResource.TMSUCCESS);
@@ -236,16 +239,32 @@ public class XADataSourceTest extends TestCase {
         xaRes.commit(xid, false);
         assertTrue(conn.getAutoCommit());
 
+        // Check that autocommit is reset to true after a 1-phase rollback
         xaRes.start(xid, XAResource.TMNOFLAGS);
         xaRes.end(xid, XAResource.TMSUCCESS);
         xaRes.rollback(xid);
         assertTrue(conn.getAutoCommit());
 
+        // Check that autocommit is reset to true after a 2-phase rollback
         xaRes.start(xid, XAResource.TMNOFLAGS);
         xaRes.end(xid, XAResource.TMSUCCESS);
         xaRes.prepare(xid);
         xaRes.rollback(xid);
         assertTrue(conn.getAutoCommit());
+
+        // Check that autoCommit is set correctly after a getConnection-call
+        conn = xaconn.getConnection();
+        assertTrue(conn.getAutoCommit());
+
+        xaRes.start(xid, XAResource.TMNOFLAGS);
+
+        conn = xaconn.getConnection();
+        assertFalse(conn.getAutoCommit());
+
+        xaRes.end(xid, XAResource.TMSUCCESS);
+        xaRes.prepare(xid);
+        xaRes.rollback(xid);
+        assertTrue(conn.getAutoCommit());
     }
 
     public void testEndThenJoin() throws XAException {
diff --git a/org/postgresql/xa/PGXAConnection.java b/org/postgresql/xa/PGXAConnection.java
index 7c9c1c8..ad6df17 100644
--- a/org/postgresql/xa/PGXAConnection.java
+++ b/org/postgresql/xa/PGXAConnection.java
@@ -34,6 +34,27 @@ public class PGXAConnection extends PooledConnectionImpl implements XAConnection
      */
     private BaseConnection conn;
 
+    /*
+     * PGXAConnection-object can be in one of three states:
+     *
+     * IDLE
+     * Not associated with a XA-transaction. You can still call 
+     * getConnection and use the connection outside XA. currentXid is null. 
+     * autoCommit is true on a connection by getConnection, per normal JDBC
+     * rules, though the caller can change it to false and manage transactions
+     * itself using Connection.commit and rollback.
+     *
+     * ACTIVE
+     * start has been called, and we're associated with an XA transaction.
+     * currentXid is valid. autoCommit is false on a connection returned by
+     * getConnection, and should not be messed with by the caller or the XA
+     * transaction will be broken.
+     *
+     * ENDED
+     * end has been called, but the transaction has not yet been prepared.
+     * currentXid is still valid. You shouldn't use the connection for anything
+     * else than issuing a XAResource.commit or rollback.
+     */
     private Xid currentXid;
 
     private int state;
@@ -58,7 +79,20 @@ public class PGXAConnection extends PooledConnectionImpl implements XAConnection
 
     public Connection getConnection() throws SQLException
     {
-        return super.getConnection();
+        Connection conn = super.getConnection();
+
+        // When we're outside an XA transaction, autocommit
+        // is supposed to be true, per usual JDBC convention.
+        // When an XA transaction is in progress, it should be
+        // false.
+
+        // super.getConnection rolls back any previous transaction, and resets
+        // autocommit to true, so we have to set it to false before handing the
+        // connection to the caller, if an XA transaction is active.
+        if(state == STATE_ACTIVE)
+            conn.setAutoCommit(false);
+
+        return conn;
     }
 
     public XAResource getXAResource() {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git



More information about the pkg-java-commits mailing list