Fixed support in jdbc for 7.3 server autocommit. With these changes the
authorBarry Lind
Thu, 17 Oct 2002 05:33:52 +0000 (05:33 +0000)
committerBarry Lind
Thu, 17 Oct 2002 05:33:52 +0000 (05:33 +0000)
jdbc regression tests pass for both autocommit on and autocommit off

 Modified Files:
  jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java
  jdbc/org/postgresql/test/jdbc2/ConnectionTest.java

src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java
src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java

index 463cfb2cca2956fd153b9c4ae434c845530df518..dbf785709b17fabc78d2b4d474d64d762baa36be 100644 (file)
@@ -14,7 +14,7 @@ import org.postgresql.largeobject.LargeObjectManager;
 import org.postgresql.util.*;
 
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.10 2002/10/01 00:39:01 davec Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.11 2002/10/17 05:33:52 barry Exp $
  * This class defines methods of the jdbc1 specification.  This class is
  * extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2
  * methods.  The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection
@@ -362,6 +362,29 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec
 
        String dbEncoding = resultSet.getString(2);
        encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
+       //In 7.3 we are forced to do a second roundtrip to handle the case 
+       //where a database may not be running in autocommit mode
+       //jdbc by default assumes autocommit is on until setAutoCommit(false)
+       //is called.  Therefore we need to ensure a new connection is 
+       //initialized to autocommit on.
+       if (haveMinimumServerVersion("7.3")) 
+       {
+           java.sql.ResultSet acRset =
+               ExecSQL("show autocommit");
+
+           if (!acRset.next())
+           {
+               throw new PSQLException("postgresql.con.failed", "failed getting autocommit status");
+           }
+           //if autocommit is currently off we need to turn it on
+           //note that we will be in a transaction because the select above
+           //will have initiated the transaction so we need a commit
+           //to make the setting permanent
+           if (acRset.getString(1).equals("off"))
+           {
+               ExecSQL("set autocommit = on; commit;");
+           }
+       }
 
        // Initialise object handling
        initObjectTypes();
@@ -896,10 +919,26 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec
        if (this.autoCommit == autoCommit)
            return ;
        if (autoCommit)
-           ExecSQL("end");
+       {
+           if (haveMinimumServerVersion("7.3"))
+           {
+                //We do the select to ensure a transaction is in process
+               //before we do the commit to avoid warning messages
+               //from issuing a commit without a transaction in process
+               ExecSQL("select 1; commit; set autocommit = on;");
+           }
+           else
+           {
+               ExecSQL("end");             
+           }
+       }
        else
        {
-           if (haveMinimumServerVersion("7.1"))
+           if (haveMinimumServerVersion("7.3"))
+           {
+               ExecSQL("set autocommit = off; " + getIsolationLevelSQL());
+           }
+           else if (haveMinimumServerVersion("7.1"))
            {
                ExecSQL("begin;" + getIsolationLevelSQL());
            }
@@ -938,7 +977,11 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec
    {
        if (autoCommit)
            return ;
-       if (haveMinimumServerVersion("7.1"))
+       if (haveMinimumServerVersion("7.3"))
+       {
+           ExecSQL("commit; " + getIsolationLevelSQL());
+       }
+       else if (haveMinimumServerVersion("7.1"))
        {
            ExecSQL("commit;begin;" + getIsolationLevelSQL());
        }
@@ -962,7 +1005,14 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec
    {
        if (autoCommit)
            return ;
-       if (haveMinimumServerVersion("7.1"))
+       if (haveMinimumServerVersion("7.3"))
+       {
+           //we don't automatically start a transaction 
+           //but let the server functionality automatically start
+           //one when the first statement is executed
+           ExecSQL("rollback; " + getIsolationLevelSQL());
+       }
+       else if (haveMinimumServerVersion("7.1"))
        {
            ExecSQL("rollback; begin;" + getIsolationLevelSQL());
        }
index e2f70f1b642e7cf07dfc3fc5844777a8993e2e6b..1d79463eb1693d8e0c310a39662a2459ccaf74d7 100644 (file)
@@ -10,7 +10,7 @@ import java.sql.*;
  *
  * PS: Do you know how difficult it is to type on a train? ;-)
  *
- * $Id: ConnectionTest.java,v 1.9 2002/08/14 20:35:40 barry Exp $
+ * $Id: ConnectionTest.java,v 1.10 2002/10/17 05:33:52 barry Exp $
  */
 
 public class ConnectionTest extends TestCase
@@ -244,18 +244,28 @@ public class ConnectionTest extends TestCase
            assertEquals(Connection.TRANSACTION_READ_COMMITTED,
                         con.getTransactionIsolation());
 
+
+           // Note the behavior on when a transaction starts is different
+           // under 7.3 than previous versions.  In 7.3 a transaction 
+           // starts with the first sql command, whereas previously 
+           // you were always in a transaction in autocommit=false
+            // so we issue a select to ensure we are in a transaction
+            Statement stmt = con.createStatement();
+            stmt.executeQuery("select 1");
+
            // Now change the default for future transactions
            con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
 
            // Since the call to setTransactionIsolation() above was made
-           // inside the transaction, the isolation level of the current
-           // transaction did not change. It affects only future transactions.
-           // This behaviour is recommended by the JDBC spec.
-           assertEquals(Connection.TRANSACTION_READ_COMMITTED,
+           // inside the transaction, the isolation level of the current
+           // transaction did not change. It affects only future ones.
+           // This behaviour is recommended by the JDBC spec.
+           assertEquals(Connection.TRANSACTION_READ_COMMITTED,
                         con.getTransactionIsolation());
 
-           // Begin a new transaction
-           con.commit();
+           // Begin a new transaction
+           con.commit();
+            stmt.executeQuery("select 1");
 
            // Now we should see the new isolation level
            assertEquals(Connection.TRANSACTION_SERIALIZABLE,