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 2005/06/09 07:26:42 UTC

svn commit: r189710 - in /incubator/derby/code/trunk/java: client/org/apache/derby/client/am/ client/org/apache/derby/client/net/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/

Author: kmarsden
Date: Wed Jun  8 22:26:41 2005
New Revision: 189710

URL: http://svn.apache.org/viewcvs?rev=189710&view=rev
Log:
DERBY-339 Network client XA should only keep XA state for transaction branch association

Network client XA should only keep XA state for transaction branch association, to track whether to send commit in autocommit mode. All other state and state related decisions should be defered to the server. 


The client tries to track XA state to make decisions based on current XA state. Most of this state handling was removed with DERBY246, but it still was not being handled properly. This is evidenced by multiple failures in xaSimplePostive that now that it gets past DERBY-246. 


This fix will have the client track only branch association as outlined in the XA+ specification. Table 6-2, State Table for Transaction Branch Association. The client will track only 

XA_TO_NOT_ASSOCIATED 
XA_T1_ASSOCIATED 

Association Suspended (T2) will map to XA_TO_NOT_ASSOCIATED for the client's pupurposes. 

The client commit in autocommit mode only for 
XA_TO_NOT_ASSOCIATED. 




Added:
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimplePositive_derby.properties   (with props)
Modified:
    incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
    incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
    incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
    incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java
    incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAResource.java
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/xaSimpleNegative.out
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/copyfiles.ant
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimpleNegative.sql

Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java Wed Jun  8 22:26:41 2005
@@ -85,13 +85,29 @@
     protected boolean isXAConnection_ = false; // Indicates an XA connection
 
     // XA States
-    public static final int XA_LOCAL = 0;   //  No global transaction in process
-    public static final int XA_GLOBAL = 1;  // Global transaction in process
-    //TODO: Remove entirely once indoubtlist is gone.  
+    // The client needs to keep track of the connection's transaction branch association
+    // per table 2.6 in the XA+ specification in order to determine if commits should flow in
+    // autocommit mode.  There is no need to keep track of suspended transactions separately from
+    // XA_TO_NOT_ASSOCIATED.
+    // 
+    /**
+     * <code>XA_T0_NOT_ASSOCIATED</code>
+     * This connection is not currently associated with an XA transaction
+     * In this state commits will flow in autocommit mode.
+     */
+    public static final int XA_T0_NOT_ASSOCIATED = 0;   
+    
+    /**
+     * <code>XA_T1_ASSOCIATED</code>
+     * In this state commits will not flow in autocommit mode.
+     */
+    public static final int XA_T1_ASSOCIATED = 1;  
+    
+    //TODO: Remove XA_RECOVER entirely once indoubtlist is gone.  
     //public static final int XA_RECOVER = 14;
 
 
-    protected int xaState_ = XA_LOCAL;
+    protected int xaState_ = XA_T0_NOT_ASSOCIATED;
 
     // XA Host Type
     public int xaHostVersion_ = 0;
@@ -524,7 +540,7 @@
 
     public void writeCommit() throws SqlException {
         if (isXAConnection_) {
-            if ((xaState_ == XA_LOCAL) ) {
+            if ((xaState_ == XA_T0_NOT_ASSOCIATED) ) {
                 writeLocalXACommit_();
             }
         } else {
@@ -541,7 +557,7 @@
 
     public void readCommit() throws SqlException {
         if (isXAConnection_) {
-            if ((xaState_ == XA_LOCAL) ) {
+            if ((xaState_ == XA_T0_NOT_ASSOCIATED) ) {
                 readLocalXACommit_();               
             }
         } else {
@@ -749,7 +765,7 @@
     * 	Might be logically closed but available for reuse.
     *   @return true if physical connection still open
     */
-    public boolean isPhysicallyClosed() {
+    public boolean isPhysicalConnClosed() {
     return !open_ && !availableForReuse_; 
    }
 

Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java Wed Jun  8 22:26:41 2005
@@ -1189,7 +1189,7 @@
         }
         if (connection_.autoCommit_ && requiresAutocommit) { // for the auto-commit;
             if (connection_.isXAConnection_) {
-                return (connection_.xaState_ == Connection.XA_LOCAL) ;
+                return (connection_.xaState_ == Connection.XA_T0_NOT_ASSOCIATED) ;
             } else {
                 return true;
             }
@@ -1268,7 +1268,7 @@
         if (connection_.autoCommit_ && requiresAutocommit && isAutoCommittableStatement_) {
             connection_.writeAutoCommit();
             if (connection_.isXAConnection_) {
-                return (connection_.xaState_ == Connection.XA_LOCAL) ;
+                return (connection_.xaState_ == Connection.XA_T0_NOT_ASSOCIATED) ;
             } else {
                 return true;
             }

Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java Wed Jun  8 22:26:41 2005
@@ -1367,7 +1367,7 @@
     // Allow local COMMIT/ROLLBACK only if we are not in an XA transaction
     protected boolean allowLocalCommitRollback_() throws org.apache.derby.client.am.SqlException {
        
-    	if (xaState_ == XA_LOCAL) {
+    	if (xaState_ == XA_T0_NOT_ASSOCIATED) {
             return true;
         }
         return false;
@@ -1471,7 +1471,7 @@
         int xaState = getXAState();
 
         
-        if (xaState == XA_LOCAL) {
+        if (xaState == XA_T0_NOT_ASSOCIATED) {
             doCommit = true;
         }
 

Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java Wed Jun  8 22:26:41 2005
@@ -132,7 +132,7 @@
         // this logic must be in sync with willAutoCommitGenerateFlow() logic
         if (isXAConnection_) { // XA Connection
             int xaState = getXAState();
-            if (xaState == XA_LOCAL){
+            if (xaState == XA_T0_NOT_ASSOCIATED){
                 xares_.callInfoArray_[xares_.conn_.currXACallInfoOffset_].xid_ =
                         NetXAResource.nullXid;
                 writeLocalXACommit_();
@@ -147,7 +147,7 @@
             int xaState = getXAState();
             NetXACallInfo callInfo = xares_.callInfoArray_[currXACallInfoOffset_];
             callInfo.xaRetVal_ = NetXAResource.XARETVAL_XAOK; // initialize XARETVAL
-            if (xaState == XA_LOCAL) {
+            if (xaState == XA_T0_NOT_ASSOCIATED) {
                 readLocalXACommit_();
                 //TODO: Remove
                 //setXAState(XA_LOCAL);
@@ -191,7 +191,7 @@
 
             // for all XA connectiions
             // TODO:KATHEY - Do we need this?
-            setXAState(XA_LOCAL);
+            setXAState(XA_T0_NOT_ASSOCIATED);
         } else {
             readLocalRollback_(); // non-XA connections
         }

Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAResource.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAResource.java?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAResource.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAResource.java Wed Jun  8 22:26:41 2005
@@ -183,7 +183,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "commit", xid, onePhase);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -215,9 +215,6 @@
         if (rc != XAResource.XA_OK) {
             throwXAException(rc, false);
         }
-        else {
-        	conn_.setXAState(Connection.XA_LOCAL);
-        }
     }
 
     /**
@@ -247,7 +244,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "end", xid, flags);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -278,8 +275,9 @@
         }
         if (rc != XAResource.XA_OK) {
             throwXAException(rc, false);
+        }else {
+        	conn_.setXAState(Connection.XA_T0_NOT_ASSOCIATED);
         } 
-
     }
 
     /**
@@ -299,7 +297,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "forget", xid);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
         NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
@@ -352,7 +350,7 @@
             conn_.agent_.logWriter_.traceEntry(this, "getTransactionTimeout");
         }
         exceptionsOnXA = null;
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -381,7 +379,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "prepare", xid);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -447,7 +445,7 @@
             conn_.agent_.logWriter_.traceEntry(this, "recover", flag);
         }
         exceptionsOnXA = null;
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -512,7 +510,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "rollback", xid);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -543,9 +541,7 @@
         if (rc != XAResource.XA_OK) {
             throwXAException(rc, false);
         }
-        else {
-        	conn_.setXAState(Connection.XA_LOCAL);
-        }
+ 
     }
 
     /**
@@ -585,7 +581,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "start", xid, flags);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -609,7 +605,7 @@
             // Setting this is currently required to avoid client from sending
             // commit for autocommit.
             if (rc == XARETVAL_XAOK) {
-                conn_.setXAState(Connection.XA_GLOBAL);
+                conn_.setXAState(Connection.XA_T1_ASSOCIATED);
             }
 
         } catch (SqlException sqle) {
@@ -626,7 +622,6 @@
 
 
     protected void throwXAException(int rc) throws XAException {
-        // By default, throwXAException will reset the state of the failed connection
         throwXAException(rc, rc != XAException.XAER_NOTA);
     }
 
@@ -735,9 +730,56 @@
                         sqlExceptions,
                         xaExceptionText);
         xaException.errorCode = rc;
+        setXaStateForXAException(rc); 
         throw xaException;
     }
 
+
+    /**
+     * Reset the transaction branch association state  to XA_T0_NOT_ASSOCIATED
+     * for XAER_RM* and XA_RB* Exceptions. All other exeptions leave the state 
+     * unchanged
+     * 
+     * @param rc  // return code from XAException
+     * @throws XAException
+     */
+    private void setXaStateForXAException(int rc) {
+    	switch (rc)
+		{
+        	// Reset to T0, not  associated for XA_RB*, RM*
+           // XAER_RMFAIL and XAER_RMERR will be fatal to the connection
+           // but that is not dealt with here
+           case javax.transaction.xa.XAException.XAER_RMFAIL:
+           case javax.transaction.xa.XAException.XAER_RMERR:
+           case javax.transaction.xa.XAException.XA_RBROLLBACK:
+           case javax.transaction.xa.XAException.XA_RBCOMMFAIL:
+           case javax.transaction.xa.XAException.XA_RBDEADLOCK:
+           case javax.transaction.xa.XAException.XA_RBINTEGRITY:
+           case javax.transaction.xa.XAException.XA_RBOTHER:
+           case javax.transaction.xa.XAException.XA_RBPROTO:
+           case javax.transaction.xa.XAException.XA_RBTIMEOUT:
+           case javax.transaction.xa.XAException.XA_RBTRANSIENT:
+           	conn_.setXAState(Connection.XA_T0_NOT_ASSOCIATED);
+           break;
+            // No change for other XAExceptions
+            // javax.transaction.xa.XAException.XA_NOMIGRATE
+           //javax.transaction.xa.XAException.XA_HEURHAZ
+           // javax.transaction.xa.XAException.XA_HEURCOM
+           // javax.transaction.xa.XAException.XA_HEURRB
+           // javax.transaction.xa.XAException.XA_HEURMIX
+           // javax.transaction.xa.XAException.XA_RETRY
+           // javax.transaction.xa.XAException.XA_RDONLY
+           // javax.transaction.xa.XAException.XAER_ASYNC
+           // javax.transaction.xa.XAException.XAER_NOTA
+           // javax.transaction.xa.XAException.XAER_INVAL                
+           // javax.transaction.xa.XAException.XAER_PROTO
+           // javax.transaction.xa.XAException.XAER_DUPID
+           // javax.transaction.xa.XAException.XAER_OUTSIDE            	
+            default:
+  			  return;
+		}	
+    }
+
     public boolean isSameRM(XAResource xares) throws XAException {
         boolean isSame = false; // preset that the RMs are NOT the same
         exceptionsOnXA = null;
@@ -745,7 +787,7 @@
         if (conn_.agent_.loggingEnabled()) {
             conn_.agent_.logWriter_.traceEntry(this, "isSameRM", xares);
         }
-        if (conn_.isPhysicallyClosed()) {
+        if (conn_.isPhysicalConnClosed()) {
             connectionClosedFailure();
         }
 
@@ -787,7 +829,7 @@
         }
         return isSame;
     }
-
+    
     public static boolean xidsEqual(Xid xid1, Xid xid2) { // determine if the 2 xids contain the same values even if not same object
         // comapre the format ids
         if (xid1.getFormatId() != xid2.getFormatId()) {

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/xaSimpleNegative.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/xaSimpleNegative.out?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/xaSimpleNegative.out (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/xaSimpleNegative.out Wed Jun  8 22:26:41 2005
@@ -2,7 +2,7 @@
 -- some negative test for error checking
 --
 xa_datasource 'wombat';
-ij> xa_connect user 'negativeTest';
+ij> xa_connect user 'negativeTest' password 'xxx';
 ij> -- start new transaction
 xa_start xa_noflags 0;
 ij> -- ERROR: cannot start without end

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/copyfiles.ant
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/copyfiles.ant?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/copyfiles.ant (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/copyfiles.ant Wed Jun  8 22:26:41 2005
@@ -63,4 +63,5 @@
 xaSimplePositive.sql
 xaSimplePositive_app.properties
 xaSimplePositive_sed.properties
+xaSimplePositive_derby.properties
 xaStateTran.sql

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimpleNegative.sql
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimpleNegative.sql?rev=189710&r1=189709&r2=189710&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimpleNegative.sql (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimpleNegative.sql Wed Jun  8 22:26:41 2005
@@ -2,7 +2,7 @@
 -- some negative test for error checking
 --
 xa_datasource 'wombat';
-xa_connect user 'negativeTest';
+xa_connect user 'negativeTest' password 'xxx';
 
 -- start new transaction
 xa_start xa_noflags 0;

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimplePositive_derby.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimplePositive_derby.properties?rev=189710&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimplePositive_derby.properties (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimplePositive_derby.properties Wed Jun  8 22:26:41 2005
@@ -0,0 +1,4 @@
+#derby.drda.debug=true
+#derby.language.logStatementText=true
+#derby.stream.error.logSeverityLevel=0
+

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/xaSimplePositive_derby.properties
------------------------------------------------------------------------------
    svn:eol-style = native