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 ma...@apache.org on 2009/08/28 18:03:27 UTC

svn commit: r808933 - in /db/derby/code/branches/10.4: ./ java/drda/org/apache/derby/impl/drda/ java/engine/org/apache/derby/iapi/jdbc/ java/engine/org/apache/derby/impl/jdbc/ java/engine/org/apache/derby/jdbc/ java/testing/org/apache/derbyTesting/func...

Author: mamta
Date: Fri Aug 28 16:03:26 2009
New Revision: 808933

URL: http://svn.apache.org/viewvc?rev=808933&view=rev
Log:
DERBY-4053

Backporting changes into 10.4 codeline. Had to do some manual conflict resolution. In 
addition, needed to manually copy following method into EmbedXAConnection which was getting
used by changes for DERBY-4053. Following method was added as part of DERBY-3319

+    /** 
+     * Check if this connection is part of a global XA transaction. 
+     * 
+     * @return {@code true} if the transaction is global, {@code false} if the 
+     * transaction is local 
+     */ 
+    private boolean isGlobal() { 
+        return xaRes.getCurrentXid () != null; 
+    } 
+ 



Modified:
    db/derby/code/branches/10.4/   (props changed)
    db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/Database.java
    db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/XADatabase.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java

Propchange: db/derby/code/branches/10.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Aug 28 16:03:26 2009
@@ -1 +1 @@
-/db/derby/code/trunk:788436,805696
+/db/derby/code/trunk:788436,793588,805696

Modified: db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/Database.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/Database.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/Database.java (original)
+++ db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/Database.java Fri Aug 28 16:03:26 2009
@@ -70,7 +70,6 @@
 	protected boolean RDBUPDRM_sent = false;	//We have sent that an update
 											// occurred in this transaction
 	protected boolean sendTRGDFTRT = false; // Send package target default value
-
     /**
      * Connection to the database in the embedded engine.
      */
@@ -80,8 +79,6 @@
 	private DRDAStatement currentStatement; // current statement we are working on
 	private Hashtable stmtTable;		// Hash table for storing statements
 
-	boolean forXA = false;
-
 	// constructor
 	/**
 	 * Database constructor
@@ -336,7 +333,12 @@
 			conn.rollback();
 	}
 	/**
-	  * Close the connection and clean up the statement table
+	  * Database close does following cleanup tasks
+	  * 1)Rollback any pending transaction on the Connection object (except 
+	  * for a global-XA Connection obejct) before closing the Connection. 
+	  * Without the rollback, the Connection close will result into an 
+	  * exception if there is a pending transaction on that Connection.
+	  * 2)Clean up the statement table 
 	  * @throws SQLException on conn.close() error to be handled in DRDAConnThread.
 	  */
 	protected void close() throws SQLException
@@ -355,7 +357,8 @@
 				defaultStatement.close();
 			if ((conn != null) && !conn.isClosed())
 			{
-				if (! forXA)
+				//rollback all the pending transactions except global XA trans
+				if (! conn.isInGlobalTransaction())
 				{
 					conn.rollback();
 				}

Modified: db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/XADatabase.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/XADatabase.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/XADatabase.java (original)
+++ db/derby/code/branches/10.4/java/drda/org/apache/derby/impl/drda/XADatabase.java Fri Aug 28 16:03:26 2009
@@ -56,7 +56,6 @@
 	XADatabase (String dbName)
 	{
 		super(dbName);
-		forXA = true;
 	}
 
 	/**

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java Fri Aug 28 16:03:26 2009
@@ -473,6 +473,11 @@
         }
 	}
 
+    /** @see EngineConnection#isInGlobalTransaction() */
+    public boolean isInGlobalTransaction() {
+    	return control.isInGlobalTransaction();
+    }
+
 	/**
 	 *  Set the internal isolation level to use for preparing statements.
 	 *  Subsequent prepares will use this isoalation level

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java Fri Aug 28 16:03:26 2009
@@ -83,6 +83,12 @@
 	*/
 	public void resetIsolationLevelFlag() throws SQLException;
 
+    /**
+     * Is this a global transaction
+     * @return true if this is a global XA transaction
+     */
+    public boolean isInGlobalTransaction();
+
 	/**
 		Close called on BrokeredConnection. If this call
 		returns true then getRealConnection().close() will be called.

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java Fri Aug 28 16:03:26 2009
@@ -40,6 +40,12 @@
      */
     public void setDrdaID(String drdaID);
 
+    /**
+     * Is this a global transaction
+     * @return true if this is a global XA transaction
+     */
+    public boolean isInGlobalTransaction();
+    
     /** 
      * Set the transaction isolation level that will be used for the 
      * next prepare.  Used by network server to implement DB2 style 

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Fri Aug 28 16:03:26 2009
@@ -2578,6 +2578,11 @@
 		getLanguageConnection().setDrdaID(drdaID);
 	}
 
+    /** @see EngineConnection#isInGlobalTransaction() */
+    public boolean isInGlobalTransaction() {
+    	return false;
+    }
+
 	/**
 		Reset the connection before it is returned from a PooledConnection
 		to a new application request (wrapped by a BrokeredConnection).

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java Fri Aug 28 16:03:26 2009
@@ -408,7 +408,11 @@
 	public void resetIsolationLevelFlag() throws SQLException {
 		realConnection.getLanguageConnection().resetIsolationLevelFlagUsedForSQLandJDBC();
 	}
-	
+
+    /** @see BrokeredConnectionControl#isInGlobalTransaction() */
+    public boolean isInGlobalTransaction() {
+    	return false;
+    }	
 	
 	/**
 		Notify the control class that a SQLException was thrown

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java Fri Aug 28 16:03:26 2009
@@ -22,6 +22,7 @@
 package org.apache.derby.jdbc;
 
 import org.apache.derby.impl.jdbc.Util;
+import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;
 import org.apache.derby.iapi.jdbc.EngineConnection;
 import org.apache.derby.iapi.jdbc.ResourceAdapter;
 
@@ -53,6 +54,21 @@
                 xaRes = new EmbedXAResource (this, ra);
 	}
 
+	/** @see BrokeredConnectionControl#isInGlobalTransaction() */
+	public boolean isInGlobalTransaction() {
+		return isGlobal();
+	}	
+
+	/**
+	  * Check if this connection is part of a global XA transaction.
+	  *
+	  * @return {@code true} if the transaction is global, {@code false} if the
+	  * transaction is local
+	*/
+	private boolean isGlobal() {
+		return xaRes.getCurrentXid () != null;
+	}
+
 	/*
 	** XAConnection methods
 	*/

Modified: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java?rev=808933&r1=808932&r2=808933&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java (original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java Fri Aug 28 16:03:26 2009
@@ -48,6 +48,55 @@
   */
 public class XATransactionTest extends BaseJDBCTestCase {
 
+	/**
+	  * This test does following 
+	  * 1)Start the network server
+	  * 2)Start a local xa transaction
+	  * 3)Do not commit the local XA transaction
+	  * 4)Shutdown the network server
+	  * 5)Start the server again
+	  * 
+	  * Before the fix for DERBY-4053 went in, step 4) would not shutdown the
+	  * server properly because of the pending local XA transaction. During the
+	  * server shutdown, we try to close all the open connections but the close 
+	  * on the XA connection results into an exception because there is still a
+	  * pending transaction. That exception is not handled by the server and
+	  * because of that, all the code necessary to shutdown the server is not
+	  * executed. The next time around, step 5), when we try to bring up the
+	  * server again, it ends up hanging
+	  * 2009-07-09 21:21:28.828 GMT : Invalid reply from network server: Insufficient data.
+	  * 2009-07-09 21:21:28.843 GMT : Could not listen on port 1527 on host 127.0.0.1: java.net.BindException: Address already in use: JVM_Bind
+	  * 
+	  * The fix for DERBY-4053 makes sure that before calling close on local XA
+	  * transaction, we first rollback any transaction active on the 
+	  * connection. 
+	 */
+	public void testPendingLocalTranAndServerShutdown() throws Exception {
+        if (usingEmbedded())
+            return;
+        //1)Server must be up already through the Derby junit framework
+        //2)Start a local xa transaction
+        XADataSource xaDataSource = J2EEDataSource.getXADataSource();
+        XAConnection xaconn = xaDataSource.getXAConnection();
+        XAResource xar = xaconn.getXAResource();
+        Connection conn = xaconn.getConnection();
+        Statement s = conn.createStatement();
+        s.executeUpdate("create table tab(i int)");
+        s.executeUpdate("insert into tab values (1),(2),(3),(4)");
+        conn.commit();
+        conn.setAutoCommit(false);
+        ResultSet rs = s.executeQuery("select * from tab");
+        rs.next();
+        //3)Do not commit this pending local XA transaction
+    	
+        //4)Shutdown the network server
+        //bring the server down while the local xa transaction is still active
+        TestConfiguration.getCurrent().stopNetworkServer();
+        
+        //5)Start the server again
+        TestConfiguration.getCurrent().startNetworkServer();
+	}
+	
     public void testGlobalXIDinTransactionTable() throws Exception {
         Statement stm = getConnection().createStatement();
         stm.execute("create table XATT2 (i int, text char(10))");