You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by km...@apache.org on 2006/05/25 23:15:22 UTC

svn commit: r409470 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/ testing/org/apache/derbyTesting/functionTe...

Author: kmarsden
Date: Thu May 25 14:15:22 2006
New Revision: 409470

URL: http://svn.apache.org/viewvc?rev=409470&view=rev
Log:
DERBY-1148 Client XA getTransactionIsolation() does not return the correct isolation level when rejoining a global transaction

Contributed by Deepa Remesh

Summary of patch:

* Changes getTransactionIsolation method in org.apache.derby.client.am.Connection class to get the isolation level from server. The built-in function "CURRENT ISOLATION" is used for this. It throws SQLException in case of failures. At the start of the method, the current auto-commit value is stored in a variable. When executing the function, auto-commit is set to false. At the end of the method, auto-commit value is restored. As it is the client which drives the auto-commit, this strategy of locally changing the auto-commit works.

* Removes the excludes for DERBY-1148 and DERBY-1035 from checkDataSource test. Adds a test for transaction suspend/resume in checkDataSource test. Updates master files

With this patch, I have run derbynetclientmats with Sun jdk 1.4.2 on Windows XP. I also ran checkDataSource.java and checkDataSource30.java with embedded and client framework. No failures


Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource30.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java?rev=409470&r1=409469&r2=409470&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java Thu May 25 14:15:22 2006
@@ -80,6 +80,10 @@
 
     // used to set transaction isolation level
     private Statement setTransactionIsolationStmt = null;
+    
+    // used to get transaction isolation level
+    private Statement getTransactionIsolationStmt = null;
+    
     // ------------------------dynamic properties---------------------------------
 
     protected boolean open_ = true;
@@ -752,6 +756,16 @@
                 accumulatedExceptions = se;
             }
         }
+        setTransactionIsolationStmt = null;
+        if (getTransactionIsolationStmt != null) {
+            try {
+                getTransactionIsolationStmt.close();
+            } catch (SQLException se) {
+                accumulatedExceptions = Utils.accumulateSQLException(
+                        se, accumulatedExceptions);
+            }
+        }
+        getTransactionIsolationStmt = null;
         try {
             flowClose();
         } catch (SqlException e) {
@@ -937,18 +951,75 @@
     }
 
     public int getTransactionIsolation() throws SQLException {
+    	
+    	// Store the current auto-commit value and use it to restore 
+    	// at the end of this method.
+    	boolean currentAutoCommit = autoCommit_;
+    	java.sql.ResultSet rs = null;
+    	
         try
         {
             checkForClosedConnection();
             if (agent_.loggingEnabled()) {
                 agent_.logWriter_.traceExit(this, "getTransactionIsolation", isolation_);
             }
-            return isolation_;
+            
+            // Set auto-commit to false when executing the statement as we do not want to
+            // cause an auto-commit from getTransactionIsolation() method. 
+            autoCommit_ = false;
+            
+            // DERBY-1148 - Client reports wrong isolation level. We need to get the isolation
+            // level from the server. 'isolation_' maintained in the client's connection object
+            // can be out of sync with the real isolation when in an XA transaction. This can 
+            // also happen when isolation is set using SQL instead of JDBC. So we try to get the
+            // value from the server by calling the "current isolation" function. If we fail to 
+            // get the value, return the value stored in the client's connection object.
+            if (getTransactionIsolationStmt == null  || 
+            		!(getTransactionIsolationStmt.openOnClient_ &&
+            				getTransactionIsolationStmt.openOnServer_)) {
+                getTransactionIsolationStmt =
+                        createStatementX(java.sql.ResultSet.TYPE_FORWARD_ONLY,
+                                java.sql.ResultSet.CONCUR_READ_ONLY,
+                                holdability());
+            }
+            
+            rs = getTransactionIsolationStmt.executeQuery("values current isolation");
+            rs.next();
+            String isolationStr = rs.getString(1);
+            isolation_ = translateIsolation(isolationStr);
+            rs.close();	
         }
         catch ( SqlException se )
         {
             throw se.getSQLException();
         }
+        finally {
+        	// Restore auto-commit value
+        	autoCommit_ = currentAutoCommit;
+        	if(rs != null)
+        		rs.close();
+        }
+        
+        return isolation_;
+    }
+  
+    /**
+     * Translates the isolation level from a SQL string to the JDBC int value
+     *  
+     * @param isolationStr SQL isolation string
+     * @return
+     */
+    private int translateIsolation(String isolationStr) {
+    	if(isolationStr.compareTo(DERBY_TRANSACTION_REPEATABLE_READ) == 0)
+    		return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
+    	else if (isolationStr.compareTo(DERBY_TRANSACTION_SERIALIZABLE) == 0)
+    		return java.sql.Connection.TRANSACTION_SERIALIZABLE;
+    	else if (isolationStr.compareTo(DERBY_TRANSACTION_READ_COMMITTED) == 0)
+    		return java.sql.Connection.TRANSACTION_READ_COMMITTED;
+    	else if (isolationStr.compareTo(DERBY_TRANSACTION_READ_UNCOMMITTED) == 0)
+    		return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
+    	else 
+    		return java.sql.Connection.TRANSACTION_NONE;
     }
 
     public java.sql.SQLWarning getWarnings() throws SQLException {

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource.out?rev=409470&r1=409469&r2=409470&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource.out Thu May 25 14:15:22 2006
@@ -287,21 +287,49 @@
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
+re-join X1
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
 back to local (same as reset)
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
+re-join X1 second time
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
+local after suspend
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
+resume X1
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
+back to local (second time)
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
 EVENT(6):connectionClosed
 new handle - local 
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
 EVENT(6):connectionClosed
+re-join with new handle X1
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
 EVENT(6):connectionClosed
 pre-X1 commit - local
   isolation level REPEATABLE_READ
   auto commit     true
   read only       false
+pre-X1 commit - X1
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
 post-X1 end - local
   isolation level REPEATABLE_READ
   auto commit     true
@@ -318,6 +346,69 @@
   read only       false
 Issue setTransactionIsolation in local transaction
 setTransactionIsolation in local
+  isolation level READ_UNCOMMITTED
+  auto commit     true
+  read only       false
+Issue SQL to change isolation in local transaction
+SQL to change isolation in local
+  isolation level SERIALIZABLE
+  auto commit     true
+  read only       false
+1st global(new)
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+local
+  isolation level SERIALIZABLE
+  auto commit     true
+  read only       false
+Issue SQL to change isolation in local transaction
+SQL to change isolation in local
+  isolation level REPEATABLE_READ
+  auto commit     true
+  read only       false
+1st global(existing)
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+local
+  isolation level REPEATABLE_READ
+  auto commit     true
+  read only       false
+2nd global(new)
+  isolation level REPEATABLE_READ
+  auto commit     false
+  read only       false
+1st global(existing)
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+local
+  isolation level REPEATABLE_READ
+  auto commit     true
+  read only       false
+1st global(existing)
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+Issue SQL to change isolation in 1st global transaction
+change isolation of existing 1st global transaction
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
+local
+  isolation level READ_UNCOMMITTED
+  auto commit     true
+  read only       false
+2nd global(existing)
+  isolation level REPEATABLE_READ
+  auto commit     false
+  read only       false
+(After 2nd global rollback) local
+  isolation level READ_UNCOMMITTED
+  auto commit     true
+  read only       false
+(After 1st global rollback) local
   isolation level READ_UNCOMMITTED
   auto commit     true
   read only       false

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource30.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource30.out?rev=409470&r1=409469&r2=409470&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource30.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/checkDataSource30.out Thu May 25 14:15:22 2006
@@ -343,11 +343,36 @@
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
+re-join X1
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
 back to local (same as reset)
   holdability     false
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
+re-join X1 second time
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
+local after suspend
+  holdability     false
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
+resume X1
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
+back to local (second time)
+  holdability     false
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
 EVENT(6):connectionClosed
 new handle - local 
   holdability     true
@@ -355,12 +380,22 @@
   auto commit     true
   read only       false
 EVENT(6):connectionClosed
+re-join with new handle X1
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
 EVENT(6):connectionClosed
 pre-X1 commit - local
   holdability     true
   isolation level REPEATABLE_READ
   auto commit     true
   read only       false
+pre-X1 commit - X1
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
 post-X1 end - local
   holdability     true
   isolation level REPEATABLE_READ
@@ -380,6 +415,84 @@
   read only       false
 Issue setTransactionIsolation in local transaction
 setTransactionIsolation in local
+  holdability     true
+  isolation level READ_UNCOMMITTED
+  auto commit     true
+  read only       false
+Issue SQL to change isolation in local transaction
+SQL to change isolation in local
+  holdability     true
+  isolation level SERIALIZABLE
+  auto commit     true
+  read only       false
+1st global(new)
+  holdability     false
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+local
+  holdability     true
+  isolation level SERIALIZABLE
+  auto commit     true
+  read only       false
+Issue SQL to change isolation in local transaction
+SQL to change isolation in local
+  holdability     true
+  isolation level REPEATABLE_READ
+  auto commit     true
+  read only       false
+1st global(existing)
+  holdability     false
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+local
+  holdability     true
+  isolation level REPEATABLE_READ
+  auto commit     true
+  read only       false
+2nd global(new)
+  holdability     false
+  isolation level REPEATABLE_READ
+  auto commit     false
+  read only       false
+1st global(existing)
+  holdability     false
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+local
+  holdability     true
+  isolation level REPEATABLE_READ
+  auto commit     true
+  read only       false
+1st global(existing)
+  holdability     false
+  isolation level SERIALIZABLE
+  auto commit     false
+  read only       false
+Issue SQL to change isolation in 1st global transaction
+change isolation of existing 1st global transaction
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       false
+local
+  holdability     true
+  isolation level READ_UNCOMMITTED
+  auto commit     true
+  read only       false
+2nd global(existing)
+  holdability     false
+  isolation level REPEATABLE_READ
+  auto commit     false
+  read only       false
+(After 2nd global rollback) local
+  holdability     true
+  isolation level READ_UNCOMMITTED
+  auto commit     true
+  read only       false
+(After 1st global rollback) local
   holdability     true
   isolation level READ_UNCOMMITTED
   auto commit     true

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out?rev=409470&r1=409469&r2=409470&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out Thu May 25 14:15:22 2006
@@ -303,6 +303,22 @@
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
+re-join X1 second time
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       true
+local after suspend
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
+resume X1
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       true
+back to local (second time)
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
 EVENT(6):connectionClosed
 new handle - local 
   isolation level READ_COMMITTED

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out?rev=409470&r1=409469&r2=409470&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out Thu May 25 14:15:22 2006
@@ -373,6 +373,26 @@
   isolation level READ_COMMITTED
   auto commit     true
   read only       false
+re-join X1 second time
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       true
+local after suspend
+  holdability     false
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
+resume X1
+  holdability     false
+  isolation level READ_UNCOMMITTED
+  auto commit     false
+  read only       true
+back to local (second time)
+  holdability     false
+  isolation level READ_COMMITTED
+  auto commit     true
+  read only       false
 EVENT(6):connectionClosed
 new handle - local 
   holdability     true

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java?rev=409470&r1=409469&r2=409470&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java Thu May 25 14:15:22 2006
@@ -82,16 +82,6 @@
 	private  boolean needRollbackBeforePCGetConnection = 
 		TestUtil.isDerbyNetClientFramework(); 
 	
-	// DERBY-1035 With client, Connection.getTransactionIsolation() return value is 
-	// wrong after changing the isolation level with an SQL statement such as 
-	// "set current isolation = RS"
-	// Tests for setting isolation level this way only run in embedded for now.
-	private boolean canSetIsolationWithStatement = TestUtil.isEmbeddedFramework();
-	  
-	//	 DERBY-1148 - Client Connection state does not
-	// get set properly when joining a global transaction.
-	private static boolean isolationSetProperlyOnJoin = TestUtil.isEmbeddedFramework();
-	
 	// DERBY-1183 getCursorName not correct after first statement execution
 	private static boolean hasGetCursorNameBug = TestUtil.isDerbyNetClientFramework();
 	
@@ -402,14 +392,28 @@
 		// and isolation level from the transaction,
 		// holdability remains that of this handle.
 		xar.start(xid, XAResource.TMJOIN);
-		// DERBY-1148
-		if (isolationSetProperlyOnJoin)
-			printState("re-join X1", cs1);
+		printState("re-join X1", cs1);
 		xar.end(xid, XAResource.TMSUCCESS);
 
 		// should be the same as the reset local
 		printState("back to local (same as reset)", cs1);
-
+		
+		// test suspend/resume
+		// now re-join the transaction, should pick up the read-only
+		// and isolation level from the transaction,
+		// holdability remains that of this handle.
+		xar.start(xid, XAResource.TMJOIN);
+		printState("re-join X1 second time", cs1);
+		
+		xar.end(xid, XAResource.TMSUSPEND);
+		printState("local after suspend", cs1);
+		
+		xar.start(xid, XAResource.TMRESUME);
+		printState("resume X1", cs1);
+		
+		xar.end(xid, XAResource.TMSUCCESS);
+		printState("back to local (second time)", cs1);
+		
 		cs1.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
 		cs1.setReadOnly(true);
 		setHoldability(cs1, true);
@@ -421,9 +425,7 @@
 		
 		xar.start(xid, XAResource.TMJOIN);
 		cs1 = xac.getConnection();
-		// DERBY-1148
-		if (isolationSetProperlyOnJoin)
-			printState("re-join with new handle X1", cs1);
+		printState("re-join with new handle X1", cs1);
 		cs1.close();
 		xar.end(xid, XAResource.TMSUCCESS);
 
@@ -434,9 +436,7 @@
 		cs1.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
 		printState("pre-X1 commit - local", cs1);
 		xar.start(xid, XAResource.TMJOIN);
-		// DERBY-1148
-		if (isolationSetProperlyOnJoin)
-			printState("pre-X1 commit - X1", cs1);
+		printState("pre-X1 commit - X1", cs1);
 		xar.end(xid, XAResource.TMSUCCESS);
 		printState("post-X1 end - local", cs1);
 		xar.commit(xid, true);
@@ -453,8 +453,7 @@
 		cs1.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
 		printState("setTransactionIsolation in local", cs1);
 
-		if (canSetIsolationWithStatement)
-			testSetIsolationWithStatement(s, xar, cs1);
+		testSetIsolationWithStatement(s, xar, cs1);
 
 		// now check re-use of *Statement objects across local/global connections.
 		System.out.println("TESTING RE_USE OF STATEMENT OBJECTS");