db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r279087 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/jdbc/ engine/org/apache/derby/iapi/sql/conn/ engine/org/apache/derby/impl/sql/conn/ engine/org/apache/derby/jdbc/ testing/org/apache/derbyTesting/functionTests/master/ tes...
Date Tue, 06 Sep 2005 20:16:35 GMT
Author: djd
Date: Tue Sep  6 13:16:24 2005
New Revision: 279087

URL: http://svn.apache.org/viewcvs?rev=279087&view=rev
Log:
DERBY-421 This patch gets the isolation level state information in BrokeredConnection in sync
with
the Real Connection's isolation level state. This is necessary because any isolation level
changes using SQL
do not get to BrokeredConnection and hence BrokeredConnection can end with the incorrect isolation
level state.
The change adds a new flag in GenericLanguageConnectionContext, namely isolationLevelSetUsingSQLorJDBC.
This flag gets set to true anytime isolation level is changed using JDBC or SQL. Later, at
the start and end of a
global transaction, EmbedXAConnection checks if the flag is set to true and if yes, it puts
the real connection's
isolation level into into BrokeredConnection and then resets the flag in GenericLanguageConnectionContext.
The reason for adding methods for this flag maintenance in both BrokeredConnection and EmbedPooledConnection
is that BrokeredConnection does not have access to GenericeLanguageConnectionContext which
has the flag.
EmbedPooledConnection does have access to GenericLanguageConnectionContext and hence the methods
in
BrokeredConnection have to go through EmbedPooledConnection. 

Patch contributed by Mamta A. Satoor msatoor@gmail.com

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java
    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/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java?rev=279087&r1=279086&r2=279087&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java Tue
Sep  6 13:16:24 2005
@@ -405,6 +405,18 @@
 	}
 
 	/**
+		Isolation level state in BrokeredConnection can get out of sync
+		if the isolation is set using SQL rather than JDBC. In order to
+		ensure correct state level information, this method is called
+		at the start and end of a global transaction.
+	*/
+	public void getIsolationUptoDate() throws SQLException {
+		if (control!=null && control.isIsolationLevelSetUsingSQLorJDBC()) {
+			stateIsolationLevel = getRealConnection().getTransactionIsolation();
+			control.resetIsolationLevelFlag();
+		}
+	}
+	/**
 		Set the state of the underlying connection according to the
 		state of this connection's view of state.
 
@@ -412,7 +424,7 @@
 		Connection, otherwise set only the Connection related state (ie.
 		the non-transaction specific state).
 
-		
+
 	*/
 	public void setState(boolean complete) throws SQLException {
 		Class[] CONN_PARAM = { Integer.TYPE };

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java?rev=279087&r1=279086&r2=279087&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
Tue Sep  6 13:16:24 2005
@@ -69,6 +69,18 @@
 	public void checkHoldCursors(int holdability) throws SQLException;
 
 	/**
+		Returns true if isolation level has been set using JDBC/SQL.
+	*/
+	public boolean isIsolationLevelSetUsingSQLorJDBC() throws SQLException;
+	/**
+		Reset the isolation level flag used to keep state in 
+		BrokeredConnection. It will get set to true when isolation level 
+		is set using JDBC/SQL. It will get reset to false at the start
+		and the end of a global transaction.
+	*/
+	public void resetIsolationLevelFlag() throws SQLException;
+
+	/**
 		Close called on BrokeredConnection. If this call
 		returns true then getRealConnection().close() will be called.
 	*/

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java?rev=279087&r1=279086&r2=279087&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
Tue Sep  6 13:16:24 2005
@@ -782,8 +782,22 @@
     public Database getDatabase();
 
 	/**
+	 * Returns true if isolation level has been set using JDBC/SQL.
+	 */
+	public boolean isIsolationLevelSetUsingSQLorJDBC();
+	/**
+	 * Reset the isolation level flag used to keep correct isolation level
+	 * state in BrokeredConnection. This resetting will happen at the start 
+	 * and end of a global transaction, after the BrokeredConection's 
+	 * isolation level state is brought upto date with the EmbedConnection's
+	 * isolation state.
+	 * The flag gets set to true when isolation level is set using JDBC/SQL.
+	 */
+	public void resetIsolationLevelFlagUsedForSQLandJDBC();
+
+	/**
 	 * Set current isolation level.
-	 * 
+	 *
 	 * @param isolationLevel	The new isolationLevel.
 	 */
 	public void setIsolationLevel(int isolationLevel) throws StandardException;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=279087&r1=279086&r2=279087&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
Tue Sep  6 13:16:24 2005
@@ -195,6 +195,22 @@
 	protected int isolationLevel = defaultIsolationLevel;
 
 	private boolean isolationLevelExplicitlySet = false;
+	// Isolation level can be changed using JDBC api Connection.setTransactionIsolation
+	// or it can be changed using SQL "set current isolation = NEWLEVEL".
+	// 
+	// In XA transactions, BrokeredConnection keeps isolation state information.
+	// When isolation is changed in XA transaction using JDBC, that state gets
+	// correctly set in BrokeredConnection.setTransactionIsolation method. But
+	// when SQL is used to set the isolation level, the code path is different
+	// and it does not go through BrokeredConnection's setTransactionIsolation
+	// method and hence the state is not maintained correctly when coming through
+	// SQL. To get around this, I am adding following flag which will get set
+	// everytime the isolation level is set using JDBC or SQL. This flag will be
+	// checked at global transaction start and end time. If the flag is set to true
+	// then BrokeredConnection's isolation level state will be brought upto date
+	// with Real Connection's isolation level and this flag will be set to false
+	// after that.
+	private boolean isolationLevelSetUsingSQLorJDBC = false;
 
 	// isolation level to when preparing statements.
 	// if unspecified, the statement won't be prepared with a specific 
@@ -2287,6 +2303,22 @@
 	{ return statementDepth; }
 
 	/**
+	 * @see LanguageConnectionContext#isIsolationLevelSetUsingSQLorJDBC
+	 */
+	public boolean isIsolationLevelSetUsingSQLorJDBC()
+	{
+		return isolationLevelSetUsingSQLorJDBC;
+	}
+
+	/**
+	 * @see LanguageConnectionContext#resetIsolationLevelFlagUsedForSQLandJDBC
+	 */
+	public void resetIsolationLevelFlagUsedForSQLandJDBC()
+	{
+		isolationLevelSetUsingSQLorJDBC = false;
+	}
+
+	/**
 	 * @see LanguageConnectionContext#setIsolationLevel
 	 */
 	public void setIsolationLevel(int isolationLevel) throws StandardException
@@ -2328,6 +2360,7 @@
 		}
 		this.isolationLevel = isolationLevel;
 		this.isolationLevelExplicitlySet = true;
+		this.isolationLevelSetUsingSQLorJDBC = true;
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java?rev=279087&r1=279086&r2=279087&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java Tue Sep
 6 13:16:24 2005
@@ -339,6 +339,27 @@
 	*/
 
 	/**
+		Returns true if isolation level has been set using either JDBC api or SQL
+	 */
+	public boolean isIsolationLevelSetUsingSQLorJDBC() throws SQLException {
+		if (realConnection != null)
+			return realConnection.getLanguageConnection().isIsolationLevelSetUsingSQLorJDBC();
+		else
+			return false;
+	}
+
+	/**
+		Reset the isolation level flag used to keep state in 
+		BrokeredConnection. It will get set to true when isolation level 
+		is set using JDBC/SQL. It will get reset to false at the start
+		and the end of a global transaction.
+	*/
+	public void resetIsolationLevelFlag() throws SQLException {
+		realConnection.getLanguageConnection().resetIsolationLevelFlagUsedForSQLandJDBC();
+	}
+	
+	
+	/**
 		Notify the control class that a SQLException was thrown
 		during a call on one of the brokered connection's methods.
 	*/

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java?rev=279087&r1=279086&r2=279087&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java Tue Sep 
6 13:16:24 2005
@@ -145,7 +145,14 @@
 						throw new XAException(XAException.XAER_OUTSIDE);
 
 					if (currentConnectionHandle != null) {
-
+						// It is possible that the isolation level state in connection
+						// handle has gotten out of sync with the real isolation level.
+						// This can happen if SLQ instead of JDBC api has been used to
+						// set the isolation level. The code below will check if isolation
+						// was set using JDBC or SQL and if yes, then it will update the
+						// isolation state in BrokeredConnection with EmbedConnection's
+						// isolation level.
+						currentConnectionHandle.getIsolationUptoDate();
 						// we have a current handle so we need to keep
 						// the connection state of the current connection.
 						currentConnectionHandle.setState(true);
@@ -167,14 +174,13 @@
 
 				realConnection.getLanguageConnection().
 					getTransactionExecute().createXATransactionFromLocalTransaction(
-						 xid_im.getFormatId(), 
+						 xid_im.getFormatId(),
 						 xid_im.getGlobalTransactionId(),
 						 xid_im.getBranchQualifier());
 
 
 			} catch (StandardException se) {
 				throw wrapInXAException(se);
-			
 			} catch (SQLException sqle) {
 				throw wrapInXAException(sqle);
 			}
@@ -254,6 +260,20 @@
 	public final synchronized void end(Xid xid, int flags) throws XAException
 	{
 		checkXAActive();
+
+		try {
+			// It is possible that the isolation level state in connection
+			// handle has gotten out of sync with the real isolation level.
+			// This can happen if SLQ instead of JDBC api has been used to
+			// set the isolation level. The code below will check if isolation
+			// was set using JDBC or SQL and if yes, then it will update the
+			// isolation state in BrokeredConnection with EmbedConnection's
+			// isolation level.
+			if (currentConnectionHandle != null)
+				currentConnectionHandle.getIsolationUptoDate();
+		} catch (SQLException sqle) {
+			throw wrapInXAException(sqle);
+		}
 
 		// ensure immtable and correct equals method.
 		XAXactId xid_im = new XAXactId(xid);

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource.out?rev=279087&r1=279086&r2=279087&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
Tue Sep  6 13:16:24 2005
@@ -317,6 +317,71 @@
   auto commit     true
   read only       false
 EVENT(6):connectionClosed
+Some more isolation testing using SQL and JDBC api
+initial local
+  isolation level READ_COMMITTED
+  auto commit     true
+  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
+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
 TESTING RE_USE OF STATEMENT OBJECTS
 THE STATEMENT OBJECTS CAN NOT BE REUSED ACROSS LOCAL/GLOBAL CONNECTIONS BECAUSE, LOCAL CONNECTION
CREATES THEM
 WITH HOLDABILITY TRUE WHEREAS GLOBAL CONNECTION CAN ONLY WORK WITH STATEMENTS WITH HOLDABILITY
FALSE

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/checkDataSource30.out?rev=279087&r1=279086&r2=279087&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
Tue Sep  6 13:16:24 2005
@@ -387,6 +387,86 @@
   auto commit     true
   read only       false
 EVENT(6):connectionClosed
+Some more isolation testing using SQL and JDBC api
+initial local
+  holdability     true
+  isolation level READ_COMMITTED
+  auto commit     true
+  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
+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
+  read only       false
 TESTING RE_USE OF STATEMENT OBJECTS
 THE STATEMENT OBJECTS CAN NOT BE REUSED ACROSS LOCAL/GLOBAL CONNECTIONS BECAUSE, LOCAL CONNECTION
CREATES THEM
 WITH HOLDABILITY TRUE WHEREAS GLOBAL CONNECTION CAN ONLY WORK WITH STATEMENTS WITH HOLDABILITY
FALSE

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/checkDataSource.java?rev=279087&r1=279086&r2=279087&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
Tue Sep  6 13:16:24 2005
@@ -358,6 +358,59 @@
 		printState("post-X1 commit - local", cs1);
 		cs1.close();
 
+		//Derby-421 Setting isolation level with SQL was not getting handled correctly 
+		System.out.println("Some more isolation testing using SQL and JDBC api");
+		cs1 = xac.getConnection();
+		s = cs1.createStatement();
+		printState("initial local", cs1);
+
+    System.out.println("Issue setTransactionIsolation in local transaction");
+		cs1.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
+		printState("setTransactionIsolation in local", cs1);
+
+    System.out.println("Issue SQL to change isolation in local transaction");
+		s.executeUpdate("set current isolation = RR");
+		printState("SQL to change isolation in local", cs1);
+
+		xid = new cdsXid(1, (byte) 35, (byte) 47);
+		xar.start(xid, XAResource.TMNOFLAGS);
+		printState("1st global(new)", cs1);
+		xar.end(xid, XAResource.TMSUCCESS);
+
+		printState("local", cs1);
+    System.out.println("Issue SQL to change isolation in local transaction");
+		s.executeUpdate("set current isolation = RS");
+		printState("SQL to change isolation in local", cs1);
+
+		Xid xid2 = new cdsXid(1, (byte) 93, (byte) 103);
+		xar.start(xid2, XAResource.TMNOFLAGS);
+		printState("2nd global(new)", cs1);
+		xar.end(xid2, XAResource.TMSUCCESS);
+
+		xar.start(xid, XAResource.TMJOIN);
+		printState("1st global(existing)", cs1);
+		xar.end(xid, XAResource.TMSUCCESS);
+
+		printState("local", cs1);
+
+		xar.start(xid, XAResource.TMJOIN);
+		printState("1st global(existing)", cs1);
+    System.out.println("Issue SQL to change isolation in 1st global transaction");
+		s.executeUpdate("set current isolation = UR");
+		printState("change isolation of existing 1st global transaction", cs1);
+		xar.end(xid, XAResource.TMSUCCESS);
+
+		printState("local", cs1);
+
+		xar.start(xid2, XAResource.TMJOIN);
+		printState("2nd global(existing)", cs1);
+		xar.end(xid2, XAResource.TMSUCCESS);
+
+		xar.rollback(xid2);
+		printState("(After 2nd global rollback) local", cs1);
+
+		xar.rollback(xid);
+		printState("(After 1st global rollback) local", cs1);
 
 		// now check re-use of *Statement objects across local/global connections.
 		System.out.println("TESTING RE_USE OF STATEMENT OBJECTS");



Mime
View raw message