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 jb...@apache.org on 2005/05/02 08:26:03 UTC
svn commit: r165585 [36/42] - in
/incubator/derby/code/trunk/java/client/org/apache/derby: client/
client/am/ client/net/ client/resources/ jdbc/
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=165585&r1=165584&r2=165585&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 Sun May 1 23:25:59 2005
@@ -38,839 +38,812 @@
**********************************************************************/
package org.apache.derby.client.net;
-import org.apache.derby.client.net.NetXACallInfo;
-import org.apache.derby.client.am.Connection;
-import org.apache.derby.client.am.SqlException;
-import java.util.*;
-import org.apache.derby.client.ClientXid;
-import javax.transaction.xa.*;
-import javax.sql.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+import javax.sql.XAConnection;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import org.apache.derby.client.ClientXid;
+import org.apache.derby.client.am.Connection;
+import org.apache.derby.client.am.SqlException;
+
+public class NetXAResource implements XAResource {
+ public static final int TMTIMEOUT = 0x00000100;
+ public static final int ACTIVE_ONLY = -1;
+ public static final int XA_NULL_XID = -1; // null Xid has Format Id of -1
+ public static final int INITIAL_CALLINFO_ELEMENTS = 1;
+ public static final int RECOVER_XID_ARRAY_LENGTH = 10;
+ public static final ClientXid nullXid = new ClientXid();
+
+ // xaretval defines
+ public static final int XARETVAL_XALCSNOTSUPP = 99; // Loosely Coupled Not Supported
+ public static final int XARETVAL_RBROLLBACK = 100; // Rollback
+ public static final int XARETVAL_RBCOMMFAIL = 101; // Rollback Communication Failure
+ public static final int XARETVAL_RBDEADLOCK = 102; // Rollback Deadlock
+ public static final int XARETVAL_RBINTEGRITY = 103; // Rollback integrity violation
+ public static final int XARETVAL_RBOTHER = 104; // Rollback Other
+ public static final int XARETVAL_RBPROTO = 105; // Rollback Protocol
+ public static final int XARETVAL_RBTIMEOUT = 106; // Rollback Timeout
+ public static final int XARETVAL_RBTRANSIENT = 107; // Rollback Transaction branch
+ public static final int XARETVAL_NODISSOCIATE = 108; // Unable to Dissociate resources from connection
+ public static final int XARETVAL_XATWOPHASE = 13; // TwoPhase commit required
+ public static final int XARETVAL_XAPROMOTED = 12; // Promoted - unused
+ public static final int XARETVAL_XADEFERRED = 11; // Deferred - unused
+ public static final int XARETVAL_XACOMMFAIL = 10; // Communication Failure
+ public static final int XARETVAL_XANOMIGRATE = 9; // No Migration
+ public static final int XARETVAL_XAHEURHAZ = 8; // Heuristically completed
+ public static final int XARETVAL_XAHEURCOM = 7; // Heuristically Commited
+ public static final int XARETVAL_XAHEURRB = 6; // Heuristically Rolledback
+ public static final int XARETVAL_XAHEURMIX = 5; // Branch heuristically commit and rollback
+ public static final int XARETVAL_XARETRY = 4; // Retry Commit
+ public static final int XARETVAL_XARDONLY = 3; // Read Only
+ public static final int XARETVAL_XAOK = 0; // OK
+ public static final int XARETVAL_XAERASYNC = -2; // Async Request not possible
+ public static final int XARETVAL_XAERRMERR = -3; // RM Error
+ public static final int XARETVAL_XAERNOTA = -4; // XID does not exist
+ public static final int XARETVAL_XAERINVAL = -5; // Invalid arguments
+ public static final int XARETVAL_XAERPROTO = -6; // Protocol Violation
+ public static final int XARETVAL_XAERRMFAIL = -7; // RM Failed
+ public static final int XARETVAL_XAERDUPID = -8; // Duplicate XID
+ public static final int XARETVAL_XAEROUTSIDE = -9; // Local tansaction active
+ public static final int XARETVAL_XAEROPENRES = -10; // Open resources
+
+ // xaFunction defines, shows which queued XA function is being performed
+ public static final int XAFUNC_NONE = 0;
+ public static final int XAFUNC_COMMIT = 1;
+ public static final int XAFUNC_END = 2;
+ public static final int XAFUNC_FORGET = 3;
+ public static final int XAFUNC_PREPARE = 4;
+ public static final int XAFUNC_RECOVER = 5;
+ public static final int XAFUNC_ROLLBACK = 6;
+ public static final int XAFUNC_START = 7;
+ public static final String XAFUNCSTR_NONE = "No XA Function";
+ public static final String XAFUNCSTR_COMMIT = "XAResource.commit()";
+ public static final String XAFUNCSTR_END = "XAResource.end()";
+ public static final String XAFUNCSTR_FORGET = "XAResource.forget()";
+ public static final String XAFUNCSTR_PREPARE = "XAResource.prepare()";
+ public static final String XAFUNCSTR_RECOVER = "XAResource.recover()";
+ public static final String XAFUNCSTR_ROLLBACK = "XAResource.rollback()";
+ public static final String XAFUNCSTR_START = "XAResource.start()";
+
+ public int nextElement = 0;
+
+ // XAResources with same RM group list
+ protected static Vector xaResourceSameRMGroup_ = new Vector();
+ protected int sameRMGroupIndex_ = 0;
+ protected NetXAResource nextSameRM_ = null;
+ protected boolean ignoreMe_ = false;
+
+ /* KATHEY CHECK THIS COMMENT TOO.
+ * Need to remove NetXAResource objects from this group when they are
+ * freed.
+ */
+
+ public org.apache.derby.client.am.SqlException exceptionsOnXA = null;
+
+ XAConnection xaconn_;
+ org.apache.derby.client.net.NetXAConnection conn_;
+ int rmId_; // unique RmId generated by XAConnection
+ // KATHEY change to a single callInfo field (not an array)
+ NetXACallInfo callInfoArray_[] =
+ new NetXACallInfo[INITIAL_CALLINFO_ELEMENTS];
+ int numXACallInfo_ = INITIAL_CALLINFO_ELEMENTS;
+ int connectionCount_ = 1;
+ int activeXATransCount_ = 0;
+ String rmIdx_; // userid in case we need to create a secondary connection
+ String rmIdy_; // password in case we need to create a secondary connection
+ // KATHEY remove port and ipaddr_
+ int port_; // port needed to make secondary connection for recover in DS mode.
+ String ipaddr_; // ip address needed to make secondary connection for recover in DS mode.
+
+ private List specialRegisters_ = Collections.synchronizedList(new LinkedList());
+
+ public NetXAResource(XAConnection xaconn, int rmId,
+ String userId, String password,
+ org.apache.derby.client.net.NetXAConnection conn) {
+ xaconn_ = xaconn;
+ rmId_ = rmId;
+ conn_ = conn;
+ rmIdx_ = userId;
+ rmIdy_ = password;
+ port_ = conn.netAgent_.getPort();
+ ipaddr_ = conn.netAgent_.socket_.getLocalAddress().getHostAddress();
+ conn.setNetXAResource(this);
+
+ // link the primary connection to the first XACallInfo element
+ conn_.currXACallInfoOffset_ = 0;
+
+ // construct the NetXACallInfo object for the array.
+ for (int i = 0; i < INITIAL_CALLINFO_ELEMENTS; ++i) {
+ callInfoArray_[i] = new NetXACallInfo(null, XAResource.TMNOFLAGS,
+ Connection.XA_OPEN_IDLE, this,
+ null);
+ }
+
+ // initialize the first XACallInfo element with the information from the
+ // primary connection
+ callInfoArray_[0].actualConn_ = conn_;
+ callInfoArray_[0].currConnection_ = true;
+ callInfoArray_[0].freeEntry_ = false;
+ // ~~~ save conn_ connection variables in callInfoArray_[0]
+ callInfoArray_[0].saveConnectionVariables();
+
+ // add this new XAResource to the list of other XAResources for the Same RM
+ initForReuse();
+ }
+
+ public void commit(Xid xid, boolean onePhase) throws XAException {
+ NetAgent netAgent = conn_.netAgent_;
+ int rc = XAResource.XA_OK;
+
+ exceptionsOnXA = null;
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "commit", xid, onePhase);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ // update the XACallInfo
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xaFlags_ = (onePhase ? XAResource.TMONEPHASE :
+ XAResource.TMNOFLAGS);
+ callInfo.xid_ = xid;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ netAgent.beginWriteChainOutsideUOW();
+ netAgent.netConnectionRequest_.writeXaCommit(conn_, xid);
+ netAgent.flowOutsideUOW();
+ netAgent.netConnectionReply_.readXaCommit(conn_);
+ if (callInfo.xaRetVal_ != XARETVAL_XAOK) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_COMMIT;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+ netAgent.endReadChain();
+ } catch (SqlException sqle) {
+ rc = XAException.XAER_RMERR;
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ }
+ }
+
+ /**
+ * Ends the work performed on behalf of a transaction branch. The resource manager dissociates the XA resource from
+ * the transaction branch specified and let the transaction be completed.
+ * <p/>
+ * If TMSUSPEND is specified in flags, the transaction branch is temporarily suspended in incomplete state. The
+ * transaction context is in suspened state and must be resumed via start with TMRESUME specified.
+ * <p/>
+ * If TMFAIL is specified, the portion of work has failed. The resource manager may mark the transaction as
+ * rollback-only
+ * <p/>
+ * If TMSUCCESS is specified, the portion of work has completed successfully.
+ *
+ * @param xid A global transaction identifier that is the same as what was used previously in the start method.
+ * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
+ *
+ * @throws XAException An error has occurred. Possible XAException values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA,
+ * XAER_INVAL, XAER_PROTO, or XA_RB*.
+ */
+
+ public void end(Xid xid, int flags) throws XAException {
+
+ NetAgent netAgent = conn_.netAgent_;
+ int rc = XAResource.XA_OK;
+ exceptionsOnXA = null;
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "end", xid, flags);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.setReadOnlyTransactionFlag(conn_.readOnlyTransaction_);
+ callInfo.xaFlags_ = flags;
+ callInfo.xid_ = xid;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ netAgent.beginWriteChainOutsideUOW();
+ netAgent.netConnectionRequest_.writeXaEndUnitOfWork(conn_);
+ netAgent.flowOutsideUOW();
+ rc = netAgent.netConnectionReply_.readXaEndUnitOfWork(conn_);
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending end
+ if (callInfo.xaRetVal_ != XARETVAL_XAOK) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_END;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+ netAgent.endReadChain();
+ } catch (SqlException sqle) {
+ rc = XAException.XAER_RMERR;
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ } else {
+ conn_.setXAState(Connection.XA_ENDED);
+ }
+
+ }
+
+ /**
+ * Tell the resource manager to forget about a heuristically (MANUALLY) completed transaction branch.
+ *
+ * @param xid A global transaction identifier
+ *
+ * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL, XAER_NOTA,
+ * XAER_INVAL, or XAER_PROTO.
+ */
+
+ public void forget(Xid xid) throws XAException {
+ NetAgent netAgent = conn_.netAgent_;
+ int rc = XAResource.XA_OK;
+ exceptionsOnXA = null;
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "forget", xid);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xid_ = xid;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ // flow the required PROTOCOL to the server
+ netAgent.beginWriteChainOutsideUOW();
+
+ // sent the commit PROTOCOL
+ netAgent.netConnectionRequest_.writeXaForget(netAgent.netConnection_, xid);
+
+ netAgent.flowOutsideUOW();
+
+ // read the reply to the commit
+ netAgent.netConnectionReply_.readXaForget(netAgent.netConnection_);
+
+ netAgent.endReadChain();
+ if (callInfo.xaRetVal_ != XARETVAL_XAOK) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_FORGET;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+ } catch (SqlException sqle) {
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ throwXAException(XAException.XAER_RMERR);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ }
+
+ }
+
+ /**
+ * Obtain the current transaction timeout value set for this XAResource instance. If
+ * <CODE>XAResource.setTransactionTimeout</CODE> was not use prior to invoking this method, the return value is the
+ * default timeout set for the resource manager; otherwise, the value used in the previous
+ * <CODE>setTransactionTimeout</CODE> call is returned.
+ *
+ * @return the transaction timeout value in seconds.
+ *
+ * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
+ */
+ public int getTransactionTimeout() throws XAException {
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "getTransactionTimeout");
+ }
+ exceptionsOnXA = null;
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceExit(this, "getTransactionTimeout", 0);
+ }
+ return 0; // we don't support transaction timeout
+ }
+
+ /**
+ * Ask the resource manager to prepare for a transaction commit of the transaction specified in xid.
+ *
+ * @param xid A global transaction identifier
+ *
+ * @return A value indicating the resource manager's vote on the outcome of the transaction. The possible values
+ * are: XA_RDONLY or XA_OK. If the resource manager wants to roll back the transaction, it should do so by
+ * raising an appropriate XAException in the prepare method.
+ *
+ * @throws XAException An error has occurred. Possible exception values are: XA_RB*, XAER_RMERR, XAER_RMFAIL,
+ * XAER_NOTA, XAER_INVAL, or XAER_PROTO.
+ */
+ public int prepare(Xid xid) throws XAException { // public interface for prepare
+ // just call prepareX with the recursion flag set to true
+ exceptionsOnXA = null;
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "prepare", xid);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ /// update the XACallInfo
+ NetAgent netAgent = conn_.netAgent_;
+ int rc = XAResource.XA_OK;
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xid_ = xid;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ netAgent.beginWriteChainOutsideUOW();
+ // sent the prepare PROTOCOL
+ netAgent.netConnectionRequest_.writeXaPrepare(conn_);
+ netAgent.flowOutsideUOW();
+
+ // read the reply to the prepare
+ rc = netAgent.netConnectionReply_.readXaPrepare(conn_);
+ if ((callInfo.xaRetVal_ != XARETVAL_XAOK) &&
+ (callInfo.xaRetVal_ != XARETVAL_XARDONLY)) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_PREPARE;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+
+ netAgent.endReadChain();
+ } catch (SqlException sqle) {
+ rc = XAException.XAER_RMERR;
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ }
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceExit(this, "prepare", rc);
+ }
+ return rc;
+ }
+
+ /**
+ * Obtain a list of prepared transaction branches from a resource manager. The transaction manager calls this method
+ * during recovery to obtain the list of transaction branches that are currently in prepared or heuristically
+ * completed states.
+ *
+ * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must be used when no other flags are set in
+ * flags.
+ *
+ * @return The resource manager returns zero or more XIDs for the transaction branches that are currently in a
+ * prepared or heuristically completed state. If an error occurs during the operation, the resource manager
+ * should raise the appropriate XAException.
+ *
+ * @throws XAException An error has occurred. Possible values are XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and
+ * XAER_PROTO.
+ */
+ public Xid[] recover(int flag) throws XAException {
+ int rc = XAResource.XA_OK;
+ NetAgent netAgent = conn_.netAgent_;
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "recover", flag);
+ }
+ exceptionsOnXA = null;
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ Xid[] xidList = null;
+ int numXid = 0;
+
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xaFlags_ = flag;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ netAgent.beginWriteChainOutsideUOW();
+ // sent the recover PROTOCOL
+ netAgent.netConnectionRequest_.writeXaRecover(conn_, flag);
+ netAgent.flowOutsideUOW();
+ netAgent.netConnectionReply_.readXaRecover(conn_);
+ if (callInfo.xaRetVal_ != XARETVAL_XAOK) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_RECOVER;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+ netAgent.endReadChain();
+ if (conn_.indoubtTransactions_ != null) {
+ numXid = conn_.indoubtTransactions_.size();
+ xidList = new Xid[numXid];
+ int i = 0;
+ nextElement = 0;
+ for (Enumeration e = conn_.indoubtTransactions_.keys();
+ e.hasMoreElements(); i++) {
+ xidList[i] = (Xid) e.nextElement();
+ }
+ }
+ } catch (SqlException sqle) {
+ rc = XAException.XAER_RMERR;
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ }
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceExit(this, "recover", xidList);
+ }
+ return xidList;
+ }
+
+ /**
+ * Inform the resource manager to roll back work done on behalf of a transaction branch
+ *
+ * @param xid A global transaction identifier
+ *
+ * @throws XAException An error has occurred
+ */
+ public void rollback(Xid xid) throws XAException {
+ NetAgent netAgent = conn_.netAgent_;
+ int rc = XAResource.XA_OK;
+ exceptionsOnXA = null;
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "rollback", xid);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ // update the XACallInfo
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xid_ = xid;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ netAgent.beginWriteChainOutsideUOW();
+ netAgent.netConnectionRequest_.writeXaRollback(conn_, xid);
+ netAgent.flowOutsideUOW();
+ // read the reply to the rollback
+ rc = netAgent.netConnectionReply_.readXaRollback(conn_);
+ netAgent.endReadChain();
+ if (callInfo.xaRetVal_ != XARETVAL_XAOK) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_END;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+ } catch (SqlException sqle) {
+ rc = XAException.XAER_RMERR;
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ }
+
+ }
+
+ /**
+ * <P>Set the current transaction timeout value for this <CODE>XAResource</CODE> instance. This value overwrites the
+ * default transaction timeout value in the resource manager. The newly assigned timeout value is effective for the
+ * life of this <CODE>XAResource</CODE> instance unless a new value is set.<P>
+ *
+ * @param the transaction timeout value in seconds.
+ *
+ * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL.
+ */
+ public boolean setTransactionTimeout(int seconds) throws XAException {
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceExit(this, "setTransactionTimeout", false);
+ }
+ exceptionsOnXA = null;
+ return false; // we don't support transaction timeout in our layer.
+ /* int rc = xaSetTransTimeOut(seconds);
+ if (rc != XAResource.XA_OK)
+ throwXAException(rc); */
+ }
-public class NetXAResource implements XAResource
-{
- public static final int TMTIMEOUT = 0x00000100;
- public static final int ACTIVE_ONLY = -1;
- public static final int XA_NULL_XID = -1; // null Xid has Format Id of -1
- public static final int INITIAL_CALLINFO_ELEMENTS = 1;
- public static final int RECOVER_XID_ARRAY_LENGTH = 10;
- public static final ClientXid nullXid = new ClientXid();
-
- // xaretval defines
- public static final int XARETVAL_XALCSNOTSUPP = 99; // Loosely Coupled Not Supported
- public static final int XARETVAL_RBROLLBACK = 100; // Rollback
- public static final int XARETVAL_RBCOMMFAIL = 101; // Rollback Communication Failure
- public static final int XARETVAL_RBDEADLOCK = 102; // Rollback Deadlock
- public static final int XARETVAL_RBINTEGRITY = 103; // Rollback integrity violation
- public static final int XARETVAL_RBOTHER = 104; // Rollback Other
- public static final int XARETVAL_RBPROTO = 105; // Rollback Protocol
- public static final int XARETVAL_RBTIMEOUT = 106; // Rollback Timeout
- public static final int XARETVAL_RBTRANSIENT = 107; // Rollback Transaction branch
- public static final int XARETVAL_NODISSOCIATE = 108; // Unable to Dissociate resources from connection
- public static final int XARETVAL_XATWOPHASE = 13; // TwoPhase commit required
- public static final int XARETVAL_XAPROMOTED = 12; // Promoted - unused
- public static final int XARETVAL_XADEFERRED = 11; // Deferred - unused
- public static final int XARETVAL_XACOMMFAIL = 10; // Communication Failure
- public static final int XARETVAL_XANOMIGRATE = 9; // No Migration
- public static final int XARETVAL_XAHEURHAZ = 8; // Heuristically completed
- public static final int XARETVAL_XAHEURCOM = 7; // Heuristically Commited
- public static final int XARETVAL_XAHEURRB = 6; // Heuristically Rolledback
- public static final int XARETVAL_XAHEURMIX = 5; // Branch heuristically commit and rollback
- public static final int XARETVAL_XARETRY = 4; // Retry Commit
- public static final int XARETVAL_XARDONLY = 3; // Read Only
- public static final int XARETVAL_XAOK = 0; // OK
- public static final int XARETVAL_XAERASYNC = -2; // Async Request not possible
- public static final int XARETVAL_XAERRMERR = -3; // RM Error
- public static final int XARETVAL_XAERNOTA = -4; // XID does not exist
- public static final int XARETVAL_XAERINVAL = -5; // Invalid arguments
- public static final int XARETVAL_XAERPROTO = -6; // Protocol Violation
- public static final int XARETVAL_XAERRMFAIL = -7; // RM Failed
- public static final int XARETVAL_XAERDUPID = -8; // Duplicate XID
- public static final int XARETVAL_XAEROUTSIDE = -9; // Local tansaction active
- public static final int XARETVAL_XAEROPENRES = -10; // Open resources
-
- // xaFunction defines, shows which queued XA function is being performed
- public static final int XAFUNC_NONE = 0;
- public static final int XAFUNC_COMMIT = 1;
- public static final int XAFUNC_END = 2;
- public static final int XAFUNC_FORGET = 3;
- public static final int XAFUNC_PREPARE = 4;
- public static final int XAFUNC_RECOVER = 5;
- public static final int XAFUNC_ROLLBACK = 6;
- public static final int XAFUNC_START = 7;
- public static final String XAFUNCSTR_NONE = "No XA Function";
- public static final String XAFUNCSTR_COMMIT = "XAResource.commit()";
- public static final String XAFUNCSTR_END = "XAResource.end()";
- public static final String XAFUNCSTR_FORGET = "XAResource.forget()";
- public static final String XAFUNCSTR_PREPARE = "XAResource.prepare()";
- public static final String XAFUNCSTR_RECOVER = "XAResource.recover()";
- public static final String XAFUNCSTR_ROLLBACK = "XAResource.rollback()";
- public static final String XAFUNCSTR_START = "XAResource.start()";
-
- public int nextElement = 0;
-
- // XAResources with same RM group list
- protected static Vector xaResourceSameRMGroup_ = new Vector();
- protected int sameRMGroupIndex_ = 0;
- protected NetXAResource nextSameRM_ = null;
- protected boolean ignoreMe_ = false;
-
- /* KATHEY CHECK THIS COMMENT TOO.
- * Need to remove NetXAResource objects from this group when they are
- * freed.
- */
-
- public org.apache.derby.client.am.SqlException exceptionsOnXA = null;
-
- XAConnection xaconn_;
- org.apache.derby.client.net.NetXAConnection conn_;
- int rmId_; // unique RmId generated by XAConnection
- // KATHEY change to a single callInfo field (not an array)
- NetXACallInfo callInfoArray_[] =
- new NetXACallInfo[INITIAL_CALLINFO_ELEMENTS];
- int numXACallInfo_ = INITIAL_CALLINFO_ELEMENTS;
- int connectionCount_ = 1;
- int activeXATransCount_ = 0;
- String rmIdx_; // userid in case we need to create a secondary connection
- String rmIdy_; // password in case we need to create a secondary connection
- // KATHEY remove port and ipaddr_
- int port_; // port needed to make secondary connection for recover in DS mode.
- String ipaddr_; // ip address needed to make secondary connection for recover in DS mode.
-
- private List specialRegisters_ = Collections.synchronizedList(new LinkedList());
- public NetXAResource( XAConnection xaconn, int rmId,
- String userId, String password,
- org.apache.derby.client.net.NetXAConnection conn )
- {
- xaconn_ = xaconn;
- rmId_ = rmId;
- conn_ = conn;
- rmIdx_ = userId;
- rmIdy_ = password;
- port_ = conn.netAgent_.getPort();
- ipaddr_ = conn.netAgent_.socket_.getLocalAddress().getHostAddress();
- conn.setNetXAResource(this);
-
- // link the primary connection to the first XACallInfo element
- conn_.currXACallInfoOffset_ = 0;
-
- // construct the NetXACallInfo object for the array.
- for (int i = 0; i < INITIAL_CALLINFO_ELEMENTS; ++i)
- callInfoArray_[i] = new NetXACallInfo(null,XAResource.TMNOFLAGS,
- Connection.XA_OPEN_IDLE, this,
- null);
-
- // initialize the first XACallInfo element with the information from the
- // primary connection
- callInfoArray_[0].actualConn_ = conn_;
- callInfoArray_[0].currConnection_ = true;
- callInfoArray_[0].freeEntry_ = false;
- // ~~~ save conn_ connection variables in callInfoArray_[0]
- callInfoArray_[0].saveConnectionVariables();
-
- // add this new XAResource to the list of other XAResources for the Same RM
- initForReuse();
- }
-
- public void commit( Xid xid, boolean onePhase ) throws XAException
- {
- NetAgent netAgent = conn_.netAgent_;
- int rc = XAResource.XA_OK;
-
- exceptionsOnXA = null;
- if (conn_.agent_.loggingEnabled())
- conn_.agent_.logWriter_.traceEntry (this, "commit", xid, onePhase);
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- // update the XACallInfo
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xaFlags_ = ( onePhase ? XAResource.TMONEPHASE:
- XAResource.TMNOFLAGS);
- callInfo.xid_ = xid;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try {
- netAgent.beginWriteChainOutsideUOW();
- netAgent.netConnectionRequest_.writeXaCommit(conn_, xid);
- netAgent.flowOutsideUOW();
- netAgent.netConnectionReply_.readXaCommit(conn_);
- if( callInfo.xaRetVal_ != XARETVAL_XAOK )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_COMMIT;
- rc = xaRetValErrorAccumSQL( callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
- netAgent.endReadChain();
- }
- catch( SqlException sqle )
- {
- rc = XAException.XAER_RMERR;
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- }
- finally
- {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
- }
-
- /** Ends the work performed on behalf of a transaction branch.
- * The resource manager dissociates the XA resource from the
- * transaction branch specified and let the transaction be
- * completed.
- *
- * If TMSUSPEND is specified in flags, the transaction branch
- * is temporarily suspended in incomplete state. The transaction
- * context is in suspened state and must be resumed via start
- * with TMRESUME specified.
- *
- * If TMFAIL is specified, the portion of work has failed.
- * The resource manager may mark the transaction as rollback-only
- *
- * If TMSUCCESS is specified, the portion of work has completed
- * successfully.
- *
- * @param xid A global transaction identifier that is the same as
- * what was used previously in the start method.
- *
- * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
- *
- * @exception XAException An error has occurred. Possible XAException
- * values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA, XAER_INVAL,
- * XAER_PROTO, or XA_RB*.
- */
-
- public void end( Xid xid, int flags ) throws XAException
- {
-
- NetAgent netAgent = conn_.netAgent_;
- int rc = XAResource.XA_OK;
- exceptionsOnXA = null;
- if (conn_.agent_.loggingEnabled())
- conn_.agent_.logWriter_.traceEntry (this, "end", xid, flags);
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.setReadOnlyTransactionFlag(conn_.readOnlyTransaction_);
- callInfo.xaFlags_ = flags;
- callInfo.xid_ = xid;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try
- {
- netAgent.beginWriteChainOutsideUOW();
- netAgent.netConnectionRequest_.writeXaEndUnitOfWork(conn_);
- netAgent.flowOutsideUOW();
- rc = netAgent.netConnectionReply_.readXaEndUnitOfWork(conn_);
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending end
- if( callInfo.xaRetVal_ != XARETVAL_XAOK )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_END;
- rc = xaRetValErrorAccumSQL( callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
- netAgent.endReadChain();
- }
- catch( SqlException sqle )
- {
- rc = XAException.XAER_RMERR;
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- }
- finally
- {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
- else
- conn_.setXAState(Connection.XA_ENDED);
-
- }
-
- /** Tell the resource manager to forget about a heuristically (MANUALLY)
- * completed transaction branch.
- *
- * @param xid A global transaction identifier
- *
- * @exception XAException An error has occurred. Possible exception
- * values are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or
- * XAER_PROTO.
- */
-
- public void forget (Xid xid) throws XAException
- {
- NetAgent netAgent = conn_.netAgent_;
- int rc = XAResource.XA_OK;
- exceptionsOnXA = null;
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry (this, "forget", xid);
- if( conn_.isClosed() )
- connectionClosedFailure();
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xid_ = xid;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try
- {
- // flow the required PROTOCOL to the server
- netAgent.beginWriteChainOutsideUOW();
-
- // sent the commit PROTOCOL
- netAgent.netConnectionRequest_.writeXaForget(netAgent.netConnection_, xid);
-
- netAgent.flowOutsideUOW();
-
- // read the reply to the commit
- netAgent.netConnectionReply_.readXaForget(netAgent.netConnection_);
-
- netAgent.endReadChain();
- if( callInfo.xaRetVal_ != XARETVAL_XAOK )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_FORGET;
- rc = xaRetValErrorAccumSQL( callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
- }
- catch( SqlException sqle )
- {
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- throwXAException(XAException.XAER_RMERR);
- }
- finally {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
-
- }
-
- /** Obtain the current transaction timeout value set for this
- * XAResource instance. If <CODE>XAResource.setTransactionTimeout</CODE>
- * was not use prior to invoking this method, the return value
- * is the default timeout set for the resource manager; otherwise,
- * the value used in the previous <CODE>setTransactionTimeout</CODE> call is
- * returned.
- *
- * @return the transaction timeout value in seconds.
- *
- * @exception XAException An error has occurred. Possible exception
- * values are XAER_RMERR, XAER_RMFAIL.
- */
- public int getTransactionTimeout() throws XAException
- {
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry (this, "getTransactionTimeout");
- exceptionsOnXA = null;
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceExit (this, "getTransactionTimeout", 0);
- return 0; // we don't support transaction timeout
- }
-
- /** Ask the resource manager to prepare for a transaction commit
- * of the transaction specified in xid.
- *
- * @param xid A global transaction identifier
- *
- * @exception XAException An error has occurred. Possible exception
- * values are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL,
- * or XAER_PROTO.
- *
- * @return A value indicating the resource manager's vote on the
- * outcome of the transaction. The possible values are: XA_RDONLY
- * or XA_OK. If the resource manager wants to roll back the
- * transaction, it should do so by raising an appropriate XAException
- * in the prepare method.
- */
- public int prepare(Xid xid) throws XAException
- { // public interface for prepare
- // just call prepareX with the recursion flag set to true
- exceptionsOnXA = null;
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry (this, "prepare", xid);
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- /// update the XACallInfo
- NetAgent netAgent = conn_.netAgent_;
- int rc = XAResource.XA_OK;
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xid_ = xid;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try {
- netAgent.beginWriteChainOutsideUOW();
- // sent the prepare PROTOCOL
- netAgent.netConnectionRequest_.writeXaPrepare(conn_);
- netAgent.flowOutsideUOW();
-
- // read the reply to the prepare
- rc = netAgent.netConnectionReply_.readXaPrepare(conn_);
- if( (callInfo.xaRetVal_ != XARETVAL_XAOK) &&
- (callInfo.xaRetVal_ != XARETVAL_XARDONLY) )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_PREPARE;
- rc = xaRetValErrorAccumSQL( callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
-
- netAgent.endReadChain();
- }
- catch( SqlException sqle )
- {
- rc = XAException.XAER_RMERR;
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- }
- finally
- {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceExit (this, "prepare", rc);
- return rc;
- }
-
- /** Obtain a list of prepared transaction branches from a resource
- * manager. The transaction manager calls this method during recovery
- * to obtain the list of transaction branches that are currently in
- * prepared or heuristically completed states.
- *
- * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS
- * must be used when no other flags are set in flags.
- *
- * @exception XAException An error has occurred. Possible values are
- * XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
- *
- * @return The resource manager returns zero or more XIDs for the
- * transaction branches that are currently in a prepared or
- * heuristically completed state. If an error occurs during the
- * operation, the resource manager should raise the appropriate
- * XAException.
- *
- */
- public Xid[] recover(int flag) throws XAException
- {
- int rc = XAResource.XA_OK;
- NetAgent netAgent = conn_.netAgent_;
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry (this, "recover", flag);
- exceptionsOnXA = null;
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- Xid[] xidList = null;
- int numXid = 0;
-
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xaFlags_ = flag;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try {
- netAgent.beginWriteChainOutsideUOW();
- // sent the recover PROTOCOL
- netAgent.netConnectionRequest_.writeXaRecover(conn_, flag);
- netAgent.flowOutsideUOW();
- netAgent.netConnectionReply_.readXaRecover(conn_);
- if( callInfo.xaRetVal_ != XARETVAL_XAOK )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_RECOVER;
- rc = xaRetValErrorAccumSQL( callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
- netAgent.endReadChain();
- if (conn_.indoubtTransactions_ != null)
- {
- numXid = conn_.indoubtTransactions_.size();
- xidList = new Xid[numXid];
- int i=0;
- nextElement = 0;
- for (Enumeration e = conn_.indoubtTransactions_.keys() ;
- e.hasMoreElements(); i++)
- {
- xidList[i] = (Xid) e.nextElement();
- }
- }
- }
- catch( SqlException sqle )
- {
- rc = XAException.XAER_RMERR;
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- }
- finally
- {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceExit (this, "recover", xidList);
- return xidList;
- }
-
- /** Inform the resource manager to roll back work done on behalf
- * of a transaction branch
- *
- * @param xid A global transaction identifier
- *
- * @exception XAException An error has occurred
- */
- public void rollback(Xid xid) throws XAException
- {
- NetAgent netAgent = conn_.netAgent_;
- int rc = XAResource.XA_OK;
- exceptionsOnXA = null;
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry (this, "rollback", xid);
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- // update the XACallInfo
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xid_ = xid;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try {
- netAgent.beginWriteChainOutsideUOW();
- netAgent.netConnectionRequest_.writeXaRollback(conn_, xid);
- netAgent.flowOutsideUOW();
- // read the reply to the rollback
- rc = netAgent.netConnectionReply_.readXaRollback(conn_);
- netAgent.endReadChain();
- if(callInfo.xaRetVal_ != XARETVAL_XAOK )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_END;
- rc = xaRetValErrorAccumSQL(callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
- }
- catch( SqlException sqle )
- {
- rc = XAException.XAER_RMERR;
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- }
- finally
- {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
-
- }
-
- /** <P>Set the current transaction timeout value for this <CODE>XAResource</CODE>
- * instance. This value overwrites the default transaction timeout
- * value in the resource manager. The newly assigned timeout value
- * is effective for the life of this <CODE>XAResource</CODE> instance unless
- * a new value is set.<P>
- *
- * @param the transaction timeout value in seconds.
- *
- * @exception XAException An error has occurred. Possible exception values
- * are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL.
- */
- public boolean setTransactionTimeout(int seconds) throws XAException
- {
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceExit (this, "setTransactionTimeout", false);
- exceptionsOnXA = null;
- return false; // we don't support transaction timeout in our layer.
- /* int rc = xaSetTransTimeOut(seconds);
- if (rc != XAResource.XA_OK)
- throwXAException(rc); */
- }
-
- /** Start work on behalf of a transaction branch specified in xid
- *
- * @param xid A global transaction identifier to be associated
- * with the resource
- *
- * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
- *
- * @exception XAException An error has occurred. Possible exceptions * are XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE,
- * XAER_NOTA, XAER_INVAL, or XAER_PROTO.
- *
- */
- public synchronized void start(Xid xid, int flags) throws XAException
- {
-
- NetAgent netAgent = conn_.netAgent_;
- int rc = XAResource.XA_OK;
- exceptionsOnXA = null;
- if (conn_.agent_.loggingEnabled())
- conn_.agent_.logWriter_.traceEntry (this, "start", xid, flags);
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- // update the XACallInfo
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xaFlags_ = flags;
- callInfo.xaInProgress_ = true;
- callInfo.xid_ = xid;
- callInfo.xaResource_ = this;
- callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
- try {
- netAgent.beginWriteChainOutsideUOW();
- netAgent.netConnectionRequest_.writeXaStartUnitOfWork(conn_);
- netAgent.flowOutsideUOW();
- netAgent.netConnectionReply_.readXaStartUnitOfWork(conn_);
- if( callInfo.xaRetVal_ != XARETVAL_XAOK )
- { // xaRetVal has possible error, format it
- callInfo.xaFunction_ = XAFUNC_START;
- rc = xaRetValErrorAccumSQL( callInfo, rc );
- callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
- }
- // Setting this is currently required to avoid client from sending
- // commit for autocommit.
- if (rc == XARETVAL_XAOK)
- conn_.setXAState(Connection.XA_ACTIVE);
-
- }
- catch( SqlException sqle )
- {
- rc = XAException.XAER_RMERR;
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (sqle, exceptionsOnXA);
- }
- finally
- {
- conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
- }
- if (rc != XAResource.XA_OK)
- throwXAException(rc, false);
- }
-
-
-
- protected void throwXAException(int rc) throws XAException
- {
- // By default, throwXAException will reset the state of the failed connection
- throwXAException(rc, rc!=XAException.XAER_NOTA);
- }
-
- private String getXAExceptionText( int rc )
- {
- String xaExceptionText;
- switch( rc )
- {
- case javax.transaction.xa.XAException.XA_RBROLLBACK:
- xaExceptionText = "XA_RBROLLBACK";
- break;
- case javax.transaction.xa.XAException.XA_RBCOMMFAIL:
- xaExceptionText = "XA_RBCOMMFAIL";
- break;
- case javax.transaction.xa.XAException.XA_RBDEADLOCK:
- xaExceptionText = "XA_RBDEADLOCK";
- break;
- case javax.transaction.xa.XAException.XA_RBINTEGRITY:
- xaExceptionText = "XA_RBINTEGRITY";
- break;
- case javax.transaction.xa.XAException.XA_RBOTHER:
- xaExceptionText = "XA_RBOTHER";
- break;
- case javax.transaction.xa.XAException.XA_RBPROTO:
- xaExceptionText = "XA_RBPROTO";
- break;
- case javax.transaction.xa.XAException.XA_RBTIMEOUT:
- xaExceptionText = "XA_RBTIMEOUT";
- break;
- case javax.transaction.xa.XAException.XA_RBTRANSIENT:
- xaExceptionText = "XA_RBTRANSIENT";
- break;
- case javax.transaction.xa.XAException.XA_NOMIGRATE:
- xaExceptionText = "XA_NOMIGRATE";
- break;
- case javax.transaction.xa.XAException.XA_HEURHAZ:
- xaExceptionText = "XA_HEURHAZ";
- break;
- case javax.transaction.xa.XAException.XA_HEURCOM:
- xaExceptionText = "XA_HEURCOM";
- break;
- case javax.transaction.xa.XAException.XA_HEURRB:
- xaExceptionText = "XA_HEURRB";
- break;
- case javax.transaction.xa.XAException.XA_HEURMIX:
- xaExceptionText = "XA_HEURMIX";
- break;
- case javax.transaction.xa.XAException.XA_RETRY:
- xaExceptionText = "XA_RETRY";
- break;
- case javax.transaction.xa.XAException.XA_RDONLY:
- xaExceptionText = "XA_RDONLY";
- break;
- case javax.transaction.xa.XAException.XAER_ASYNC:
- xaExceptionText = "XAER_ASYNC";
- break;
- case javax.transaction.xa.XAException.XAER_RMERR:
- xaExceptionText = "XAER_RMERR";
- break;
- case javax.transaction.xa.XAException.XAER_NOTA:
- xaExceptionText = "XAER_NOTA";
- break;
- case javax.transaction.xa.XAException.XAER_INVAL:
- xaExceptionText = "XAER_INVAL";
- break;
- case javax.transaction.xa.XAException.XAER_PROTO:
- xaExceptionText = "XAER_PROTO";
- break;
- case javax.transaction.xa.XAException.XAER_RMFAIL:
- xaExceptionText = "XAER_RMFAIL";
- break;
- case javax.transaction.xa.XAException.XAER_DUPID:
- xaExceptionText = "XAER_DUPID";
- break;
- case javax.transaction.xa.XAException.XAER_OUTSIDE:
- xaExceptionText = "XAER_OUTSIDE";
- break;
- case XAResource.XA_OK:
- xaExceptionText = "XA_OK";
- break;
- default:
- xaExceptionText = "Unknown Error";
- break;
- }
- return xaExceptionText;
- }
-
- protected void throwXAException(int rc, boolean resetFlag) throws XAException
- { // ~~~
- String xaExceptionText;
- if (resetFlag)
- {
- // reset the state of the failed connection
- NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
- callInfo.xaInProgress_ = false;
- callInfo.xaWasSuspended = false;
- callInfo.xaState_ = Connection.XA_OPEN_IDLE;
- conn_.setXAState( Connection.XA_OPEN_IDLE );
- }
-
- xaExceptionText = getXAExceptionText( rc );
- // save the SqlException chain to add it to the XAException
- org.apache.derby.client.am.SqlException sqlExceptions = exceptionsOnXA;
-
- while( exceptionsOnXA != null )
- { // one or more SqlExceptions received, format them
- xaExceptionText = xaExceptionText + " : " + exceptionsOnXA.getMessage();
- exceptionsOnXA = (org.apache.derby.client.am.SqlException)
- exceptionsOnXA.getNextException();
- }
- org.apache.derby.client.am.XaException xaException =
- new org.apache.derby.client.am.XaException( conn_.agent_.logWriter_,
- sqlExceptions,
- xaExceptionText );
- xaException.errorCode = rc;
- throw xaException;
- }
-
- public boolean isSameRM(XAResource xares) throws XAException
- {
- boolean isSame = false; // preset that the RMs are NOT the same
- exceptionsOnXA = null;
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry (this, "isSameRM", xares);
- if( conn_.isClosed() )
- connectionClosedFailure();
-
- if ( xares instanceof org.apache.derby.client.net.NetXAResource )
- { // both are NetXAResource so check to see if this is the same RM
- // remember, isSame is initialized to false
- NetXAResource derbyxares = (NetXAResource) xares;
- while( true )
- {
- if( !conn_.databaseName_.equalsIgnoreCase(derbyxares.conn_.databaseName_) )
- break; // database names are not equal, not same RM
- if( !conn_.netAgent_.server_.equalsIgnoreCase
- (derbyxares.conn_.netAgent_.server_) )
- { // server name strings not equal, compare IP addresses
- try
- {
- // 1st convert "localhost" to actual server name
- String server1 = this.processLocalHost( conn_.netAgent_.server_ );
- String server2 =
- this.processLocalHost( derbyxares.conn_.netAgent_.server_ );
- // now convert the server name to ip address
- InetAddress serverIP1 = InetAddress.getByName( server1 );
- InetAddress serverIP2 = InetAddress.getByName( server2 );
- if( !serverIP1.equals( serverIP2 ) )
- break; // server IPs are not equal, not same RM
- }
- catch( UnknownHostException ue ) {break;}
- }
- if( conn_.netAgent_.port_ != derbyxares.conn_.netAgent_.port_ )
- break; // ports are not equal, not same RM
- isSame = true; // everything the same, set RMs are the same
- break;
- }
- }
-
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceExit
- (this, "isSameRM", isSame);
- 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() )
- return false; // format ids are not the same
-
- // compare the global transaction ids
- int xid1Length = xid1.getGlobalTransactionId().length;
- if( xid1Length != xid2.getGlobalTransactionId().length )
- return false; // length of the global trans ids are not the same
- byte[] xid1Bytes = xid1.getGlobalTransactionId();
- byte[] xid2Bytes = xid2.getGlobalTransactionId();
- int i;
- for( i=0; i<xid1Length; ++i )
- { // check all bytes are the same
- if( xid1Bytes[i] != xid2Bytes[i] )
- return false; // bytes in the global trans ids are not the same
- }
-
- // compare the branch qualifiers
- xid1Length = xid1.getBranchQualifier().length;
- if( xid1Length != xid2.getBranchQualifier().length )
- return false; // length of the global trans ids are not the same
- xid1Bytes = xid1.getBranchQualifier();
- xid2Bytes = xid2.getBranchQualifier();
- for( i=0; i<xid1Length; ++i )
- { // check all bytes are the same
- if( xid1Bytes[i] != xid2Bytes[i] )
- return false; // bytes in the global trans ids are not the same
- }
-
- return true; // all of the fields are the same, xid1 == xid2
- }
-
-
- // KATHEY remove
- protected void makeEntryCurrent( int offset ) throws SqlException
- {
- int currOffset = conn_.currXACallInfoOffset_; // offset of current XACallInfo
- NetXACallInfo newCallInfo = callInfoArray_[offset];
- if (conn_.agent_.loggingEnabled()) conn_.agent_.logWriter_.traceEntry
- (this, "makeEntryCurrent", offset, currOffset);
-
- if( currOffset == offset )
- { // entry is already current
- if( newCallInfo.convReleased_ &&
- !newCallInfo.xaInProgress_ )
- { // connection reuse, XA is not in Progress, reset connection
- // transaction pooling
- newCallInfo.convReleased_ = false;
- if( !conn_.resetConnectionAtFirstSql_ )
- { // resetConnectionAtFirstSql_ is false
- /*
+ /**
+ * Start work on behalf of a transaction branch specified in xid
+ *
+ * @param xid A global transaction identifier to be associated with the resource
+ * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
+ *
+ * @throws XAException An error has occurred. Possible exceptions * are XA_RB*, XAER_RMERR, XAER_RMFAIL,
+ * XAER_DUPID, XAER_OUTSIDE, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
+ */
+ public synchronized void start(Xid xid, int flags) throws XAException {
+
+ NetAgent netAgent = conn_.netAgent_;
+ int rc = XAResource.XA_OK;
+ exceptionsOnXA = null;
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "start", xid, flags);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ // update the XACallInfo
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xaFlags_ = flags;
+ callInfo.xaInProgress_ = true;
+ callInfo.xid_ = xid;
+ callInfo.xaResource_ = this;
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // initialize XARETVAL
+ try {
+ netAgent.beginWriteChainOutsideUOW();
+ netAgent.netConnectionRequest_.writeXaStartUnitOfWork(conn_);
+ netAgent.flowOutsideUOW();
+ netAgent.netConnectionReply_.readXaStartUnitOfWork(conn_);
+ if (callInfo.xaRetVal_ != XARETVAL_XAOK) { // xaRetVal has possible error, format it
+ callInfo.xaFunction_ = XAFUNC_START;
+ rc = xaRetValErrorAccumSQL(callInfo, rc);
+ callInfo.xaRetVal_ = XARETVAL_XAOK; // re-initialize XARETVAL
+ }
+ // Setting this is currently required to avoid client from sending
+ // commit for autocommit.
+ if (rc == XARETVAL_XAOK) {
+ conn_.setXAState(Connection.XA_ACTIVE);
+ }
+
+ } catch (SqlException sqle) {
+ rc = XAException.XAER_RMERR;
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (sqle, exceptionsOnXA);
+ } finally {
+ conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
+ }
+ if (rc != XAResource.XA_OK) {
+ throwXAException(rc, false);
+ }
+ }
+
+
+ protected void throwXAException(int rc) throws XAException {
+ // By default, throwXAException will reset the state of the failed connection
+ throwXAException(rc, rc != XAException.XAER_NOTA);
+ }
+
+ private String getXAExceptionText(int rc) {
+ String xaExceptionText;
+ switch (rc) {
+ case javax.transaction.xa.XAException.XA_RBROLLBACK:
+ xaExceptionText = "XA_RBROLLBACK";
+ break;
+ case javax.transaction.xa.XAException.XA_RBCOMMFAIL:
+ xaExceptionText = "XA_RBCOMMFAIL";
+ break;
+ case javax.transaction.xa.XAException.XA_RBDEADLOCK:
+ xaExceptionText = "XA_RBDEADLOCK";
+ break;
+ case javax.transaction.xa.XAException.XA_RBINTEGRITY:
+ xaExceptionText = "XA_RBINTEGRITY";
+ break;
+ case javax.transaction.xa.XAException.XA_RBOTHER:
+ xaExceptionText = "XA_RBOTHER";
+ break;
+ case javax.transaction.xa.XAException.XA_RBPROTO:
+ xaExceptionText = "XA_RBPROTO";
+ break;
+ case javax.transaction.xa.XAException.XA_RBTIMEOUT:
+ xaExceptionText = "XA_RBTIMEOUT";
+ break;
+ case javax.transaction.xa.XAException.XA_RBTRANSIENT:
+ xaExceptionText = "XA_RBTRANSIENT";
+ break;
+ case javax.transaction.xa.XAException.XA_NOMIGRATE:
+ xaExceptionText = "XA_NOMIGRATE";
+ break;
+ case javax.transaction.xa.XAException.XA_HEURHAZ:
+ xaExceptionText = "XA_HEURHAZ";
+ break;
+ case javax.transaction.xa.XAException.XA_HEURCOM:
+ xaExceptionText = "XA_HEURCOM";
+ break;
+ case javax.transaction.xa.XAException.XA_HEURRB:
+ xaExceptionText = "XA_HEURRB";
+ break;
+ case javax.transaction.xa.XAException.XA_HEURMIX:
+ xaExceptionText = "XA_HEURMIX";
+ break;
+ case javax.transaction.xa.XAException.XA_RETRY:
+ xaExceptionText = "XA_RETRY";
+ break;
+ case javax.transaction.xa.XAException.XA_RDONLY:
+ xaExceptionText = "XA_RDONLY";
+ break;
+ case javax.transaction.xa.XAException.XAER_ASYNC:
+ xaExceptionText = "XAER_ASYNC";
+ break;
+ case javax.transaction.xa.XAException.XAER_RMERR:
+ xaExceptionText = "XAER_RMERR";
+ break;
+ case javax.transaction.xa.XAException.XAER_NOTA:
+ xaExceptionText = "XAER_NOTA";
+ break;
+ case javax.transaction.xa.XAException.XAER_INVAL:
+ xaExceptionText = "XAER_INVAL";
+ break;
+ case javax.transaction.xa.XAException.XAER_PROTO:
+ xaExceptionText = "XAER_PROTO";
+ break;
+ case javax.transaction.xa.XAException.XAER_RMFAIL:
+ xaExceptionText = "XAER_RMFAIL";
+ break;
+ case javax.transaction.xa.XAException.XAER_DUPID:
+ xaExceptionText = "XAER_DUPID";
+ break;
+ case javax.transaction.xa.XAException.XAER_OUTSIDE:
+ xaExceptionText = "XAER_OUTSIDE";
+ break;
+ case XAResource.XA_OK:
+ xaExceptionText = "XA_OK";
+ break;
+ default:
+ xaExceptionText = "Unknown Error";
+ break;
+ }
+ return xaExceptionText;
+ }
+
+ protected void throwXAException(int rc, boolean resetFlag) throws XAException { // ~~~
+ String xaExceptionText;
+ if (resetFlag) {
+ // reset the state of the failed connection
+ NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
+ callInfo.xaInProgress_ = false;
+ callInfo.xaWasSuspended = false;
+ callInfo.xaState_ = Connection.XA_OPEN_IDLE;
+ conn_.setXAState(Connection.XA_OPEN_IDLE);
+ }
+
+ xaExceptionText = getXAExceptionText(rc);
+ // save the SqlException chain to add it to the XAException
+ org.apache.derby.client.am.SqlException sqlExceptions = exceptionsOnXA;
+
+ while (exceptionsOnXA != null) { // one or more SqlExceptions received, format them
+ xaExceptionText = xaExceptionText + " : " + exceptionsOnXA.getMessage();
+ exceptionsOnXA = (org.apache.derby.client.am.SqlException)
+ exceptionsOnXA.getNextException();
+ }
+ org.apache.derby.client.am.XaException xaException =
+ new org.apache.derby.client.am.XaException(conn_.agent_.logWriter_,
+ sqlExceptions,
+ xaExceptionText);
+ xaException.errorCode = rc;
+ throw xaException;
+ }
+
+ public boolean isSameRM(XAResource xares) throws XAException {
+ boolean isSame = false; // preset that the RMs are NOT the same
+ exceptionsOnXA = null;
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry(this, "isSameRM", xares);
+ }
+ if (conn_.isClosed()) {
+ connectionClosedFailure();
+ }
+
+ if (xares instanceof org.apache.derby.client.net.NetXAResource) { // both are NetXAResource so check to see if this is the same RM
+ // remember, isSame is initialized to false
+ NetXAResource derbyxares = (NetXAResource) xares;
+ while (true) {
+ if (!conn_.databaseName_.equalsIgnoreCase(derbyxares.conn_.databaseName_)) {
+ break; // database names are not equal, not same RM
+ }
+ if (!conn_.netAgent_.server_.equalsIgnoreCase
+ (derbyxares.conn_.netAgent_.server_)) { // server name strings not equal, compare IP addresses
+ try {
+ // 1st convert "localhost" to actual server name
+ String server1 = this.processLocalHost(conn_.netAgent_.server_);
+ String server2 =
+ this.processLocalHost(derbyxares.conn_.netAgent_.server_);
+ // now convert the server name to ip address
+ InetAddress serverIP1 = InetAddress.getByName(server1);
+ InetAddress serverIP2 = InetAddress.getByName(server2);
+ if (!serverIP1.equals(serverIP2)) {
+ break; // server IPs are not equal, not same RM
+ }
+ } catch (UnknownHostException ue) {
+ break;
+ }
+ }
+ if (conn_.netAgent_.port_ != derbyxares.conn_.netAgent_.port_) {
+ break; // ports are not equal, not same RM
+ }
+ isSame = true; // everything the same, set RMs are the same
+ break;
+ }
+ }
+
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceExit
+ (this, "isSameRM", isSame);
+ }
+ 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()) {
+ return false; // format ids are not the same
+ }
+
+ // compare the global transaction ids
+ int xid1Length = xid1.getGlobalTransactionId().length;
+ if (xid1Length != xid2.getGlobalTransactionId().length) {
+ return false; // length of the global trans ids are not the same
+ }
+ byte[] xid1Bytes = xid1.getGlobalTransactionId();
+ byte[] xid2Bytes = xid2.getGlobalTransactionId();
+ int i;
+ for (i = 0; i < xid1Length; ++i) { // check all bytes are the same
+ if (xid1Bytes[i] != xid2Bytes[i]) {
+ return false; // bytes in the global trans ids are not the same
+ }
+ }
+
+ // compare the branch qualifiers
+ xid1Length = xid1.getBranchQualifier().length;
+ if (xid1Length != xid2.getBranchQualifier().length) {
+ return false; // length of the global trans ids are not the same
+ }
+ xid1Bytes = xid1.getBranchQualifier();
+ xid2Bytes = xid2.getBranchQualifier();
+ for (i = 0; i < xid1Length; ++i) { // check all bytes are the same
+ if (xid1Bytes[i] != xid2Bytes[i]) {
+ return false; // bytes in the global trans ids are not the same
+ }
+ }
+
+ return true; // all of the fields are the same, xid1 == xid2
+ }
+
+
+ // KATHEY remove
+ protected void makeEntryCurrent(int offset) throws SqlException {
+ int currOffset = conn_.currXACallInfoOffset_; // offset of current XACallInfo
+ NetXACallInfo newCallInfo = callInfoArray_[offset];
+ if (conn_.agent_.loggingEnabled()) {
+ conn_.agent_.logWriter_.traceEntry
+ (this, "makeEntryCurrent", offset, currOffset);
+ }
+
+ if (currOffset == offset) { // entry is already current
+ if (newCallInfo.convReleased_ &&
+ !newCallInfo.xaInProgress_) { // connection reuse, XA is not in Progress, reset connection
+// transaction pooling
+ newCallInfo.convReleased_ = false;
+ if (!conn_.resetConnectionAtFirstSql_) { // resetConnectionAtFirstSql_ is false
+/*
* at this point we have determined that a reset of this connection
* is required. We are already inside beginWriteChain() where a
* deferred reset would be done, however we might have switched
@@ -882,30 +855,28 @@
* resetConnectionAtFirstSql_ is not set, if it is then
* writeDeferredReset() has already been done.
*/
- conn_.resetConnectionAtFirstSql_ = true;
- conn_.writeDeferredReset();
+ conn_.resetConnectionAtFirstSql_ = true;
+ conn_.writeDeferredReset();
+ }
+ }
+ return; // entry is already current, nothing to do
}
- }
- return; // entry is already current, nothing to do
- }
- callInfoArray_[currOffset].currConnection_ = false; // reset old current conn
- callInfoArray_[currOffset].xaState_ = conn_.getXAState(); // save XA state
- callInfoArray_[currOffset].freeEntry_ = false; // set entry in use
-
- // set the new entry as the current entry, update conn_
- newCallInfo.currConnection_ = true;
- conn_.currXACallInfoOffset_ = offset;
- conn_.setXAState(newCallInfo.xaState_);
-
- if( newCallInfo.convReleased_ &&
- !newCallInfo.xaInProgress_ )
- { // connection reuse, XA is not in Progress, reset connection
- // transaction pooling
- newCallInfo.convReleased_ = false;
- if( !conn_.resetConnectionAtFirstSql_ )
- { // resetConnectionAtFirstSql_ is false
- /*
+ callInfoArray_[currOffset].currConnection_ = false; // reset old current conn
+ callInfoArray_[currOffset].xaState_ = conn_.getXAState(); // save XA state
+ callInfoArray_[currOffset].freeEntry_ = false; // set entry in use
+
+// set the new entry as the current entry, update conn_
+ newCallInfo.currConnection_ = true;
+ conn_.currXACallInfoOffset_ = offset;
+ conn_.setXAState(newCallInfo.xaState_);
+
+ if (newCallInfo.convReleased_ &&
+ !newCallInfo.xaInProgress_) { // connection reuse, XA is not in Progress, reset connection
+// transaction pooling
+ newCallInfo.convReleased_ = false;
+ if (!conn_.resetConnectionAtFirstSql_) { // resetConnectionAtFirstSql_ is false
+/*
* at this point we have determined that a reset of this connection
* is required. We are already inside beginWriteChain() where a
* deferred reset would be done, however we might have switched
@@ -917,277 +888,234 @@
* resetConnectionAtFirstSql_ is not set, if it is then
* writeDeferredReset() has already been done.
*/
- conn_.resetConnectionAtFirstSql_ = true;
- conn_.writeDeferredReset();
- }
- }
-
- if( conn_.agent_.loggingEnabled() )
- { // logging enabled
- conn_.agent_.logWriter_.traceExit (this, "makeEntryCurrent", offset);
- }
- }
-
-
- public List getSpecialRegisters()
- {
- return specialRegisters_;
- }
-
- public void addSpecialRegisters(String s)
- {
- if (s.substring(0,1).equals("@"))
- {
- // SET statement is coming from Client
- if (specialRegisters_.remove(s.substring(1)))
- {
- specialRegisters_.remove(s);
- specialRegisters_.add(s.substring(1));
- }
- else
- {
- specialRegisters_.remove(s);
- specialRegisters_.add(s);
- }
- }
- else
- { // SET statement is coming from Server
- specialRegisters_.remove(s);
- specialRegisters_.add(s);
- }
- }
-
- private void connectionClosedFailure() throws XAException
- { // throw an XAException XAER_RMFAIL, with a chained SqlException - closed
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (new SqlException( null, "Connection is Closed."),
- exceptionsOnXA);
- throwXAException(javax.transaction.xa.XAException.XAER_RMFAIL);
- }
-
- private String getXAFuncStr( int xaFunc )
- {
- switch( xaFunc )
- {
- case XAFUNC_COMMIT:
- return XAFUNCSTR_COMMIT;
- case XAFUNC_END:
- return XAFUNCSTR_END;
- case XAFUNC_FORGET:
- return XAFUNCSTR_FORGET;
- case XAFUNC_PREPARE:
- return XAFUNCSTR_PREPARE;
- case XAFUNC_RECOVER:
- return XAFUNCSTR_RECOVER;
- case XAFUNC_ROLLBACK:
- return XAFUNCSTR_ROLLBACK;
- case XAFUNC_START:
- return XAFUNCSTR_START;
- }
- return XAFUNCSTR_NONE;
- }
-
- protected int xaRetValErrorAccumSQL( NetXACallInfo callInfo, int currentRC )
- {
- int rc;
- switch (callInfo.xaRetVal_)
- {
- case XARETVAL_XAOK:
- case XARETVAL_NODISSOCIATE:
- rc = XAResource.XA_OK;
- break;
- case XARETVAL_XALCSNOTSUPP:
- rc = XAResource.XA_OK;
- break;
- case XARETVAL_RBROLLBACK:
- rc = XAException.XA_RBROLLBACK;
- break;
- case XARETVAL_RBOTHER:
- rc = XAException.XA_RBOTHER;
- break;
- case XARETVAL_RBDEADLOCK:
- rc = XAException.XA_RBDEADLOCK;
- break;
- case XARETVAL_RBPROTO:
- rc = XAException.XA_RBPROTO;
- break;
- case XARETVAL_XAERPROTO:
- rc = XAException.XAER_PROTO;
- break;
- case XARETVAL_XARDONLY:
- rc = XAException.XA_RDONLY;
- break;
- case XARETVAL_XAHEURCOM:
- rc = XAException.XA_HEURCOM;
- break;
- case XARETVAL_XAHEURRB:
- rc = XAException.XA_HEURRB;
- break;
- case XARETVAL_XAERDUPID:
- rc = XAException.XAER_DUPID;
- break;
- case XARETVAL_XAERNOTA:
- rc = XAException.XAER_NOTA;
- break;
- case XARETVAL_XAERRMERR:
- rc = XAException.XAER_RMERR;
- break;
- case XARETVAL_XAERRMFAIL:
- rc = XAException.XAER_RMFAIL;
- break;
- case XARETVAL_XAERINVAL:
- rc = XAException.XAER_INVAL;
- break;
- default:
- rc = XAException.XAER_RMFAIL;
- break;
- }
-
- if( rc != XAResource.XA_OK )
- { // error was detected
- // create an SqlException to report this error within
- String xaRetValStr = "Error executing a " +
- getXAFuncStr( callInfo.xaFunction_ ) + ", " +
- "Server returned " + getXAExceptionText( rc );
- SqlException accumSql = new SqlException( conn_.netAgent_.logWriter_,
- xaRetValStr, org.apache.derby.client.am.SqlState.undefined,
- org.apache.derby.client.am.SqlCode.queuedXAError );
- exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
- (accumSql, exceptionsOnXA);
-
- if( currentRC != XAResource.XA_OK )
- { // the rc passed into this function had an error also, prioritize error
- if( currentRC < 0 )
- { // rc passed in was a major error use it instead of current error
- return currentRC;
- }
- }
- }
- return rc;
- }
-
- private String processLocalHost( String serverName )
- {
- if( serverName.equalsIgnoreCase("localhost") )
- { // this is a localhost, find hostname
- try
- {
- InetAddress localhostNameIA = InetAddress.getLocalHost();
- String localhostName = localhostNameIA.getHostName();
- return localhostName;
- }
- catch( SecurityException se ) {return serverName;}
- catch( UnknownHostException ue ) {return serverName;}
- }
- // not "localhost", return original server name
- return serverName;
- }
-
- protected void removeXaresFromSameRMchain()
- {
- // check all NetXAResources on the same RM for the NetXAResource to remove
- try
- {
- this.ignoreMe_ = true; // use the ignoreMe_ flag to indicate the
- // XAResource to remove
- NetXAResource prevXAResource = null;
- NetXAResource currXAResource;
- synchronized( xaResourceSameRMGroup_ )
- { // make sure no one changes this vector list
- currXAResource = (NetXAResource) xaResourceSameRMGroup_.elementAt(
- sameRMGroupIndex_ );
- while( currXAResource != null )
- { // is this the XAResource to remove?
- if( currXAResource.ignoreMe_ )
- { // this NetXAResource is the one to remove
- if( prevXAResource != null )
- { // this XAResource is not first in chain, just move next to prev
- prevXAResource.nextSameRM_ = currXAResource.nextSameRM_;
+ conn_.resetConnectionAtFirstSql_ = true;
+ conn_.writeDeferredReset();
}
- else
- { // this XAResource is first in chain, just move next to root
- xaResourceSameRMGroup_.set( sameRMGroupIndex_,
- currXAResource.nextSameRM_ );
+ }
+
+ if (conn_.agent_.loggingEnabled()) { // logging enabled
+ conn_.agent_.logWriter_.traceExit(this, "makeEntryCurrent", offset);
+ }
+ }
+
+
+ public List getSpecialRegisters() {
+ return specialRegisters_;
+ }
+
+ public void addSpecialRegisters(String s) {
+ if (s.substring(0, 1).equals("@")) {
+ // SET statement is coming from Client
+ if (specialRegisters_.remove(s.substring(1))) {
+ specialRegisters_.remove(s);
+ specialRegisters_.add(s.substring(1));
+ } else {
+ specialRegisters_.remove(s);
+ specialRegisters_.add(s);
}
- return;
- }
- // this is not the NetXAResource to remove, try the next one
- prevXAResource = currXAResource;
- currXAResource = currXAResource.nextSameRM_;
- }
- }
- }
- finally
- {
- this.ignoreMe_ = false;
- }
- }
-
-
- public void initForReuse()
- {
- // add this new XAResource to the list of other XAResources for the Same RM
- // first find out if there are any other XAResources for the same RM
- // then check to make sure it is not already in the chain
- synchronized(xaResourceSameRMGroup_)
- { // make sure no one changes this vector list
- int groupCount = xaResourceSameRMGroup_.size();
- int index = 0;
- int firstFreeElement = -1;
- NetXAResource xaResourceGroup = null;
-
- for( ; index<groupCount; ++index )
- { // check if this group is the same RM
- xaResourceGroup = (NetXAResource) xaResourceSameRMGroup_.elementAt( index );
- if( xaResourceGroup == null )
- { // this is a free element, save its index if first found
- if( firstFreeElement == -1 )
- { // first free element, save index
- firstFreeElement = index;
- }
- continue; // go to next element
- }
- try
- {
- if( xaResourceGroup.isSameRM(this) )
- { // it is the same RM add this XAResource to the chain if not there
- NetXAResource nextXares = (NetXAResource)
- xaResourceSameRMGroup_.elementAt( sameRMGroupIndex_ );
- while( nextXares != null )
- { // is this NetXAResource the one we are trying to add?
- if( nextXares.equals( this ) )
- { // the XAResource to be added already is in chain, don't add
- break;
- }
- // Xid was not on that NetXAResource, try the next one
- nextXares = nextXares.nextSameRM_;
+ } else { // SET statement is coming from Server
+ specialRegisters_.remove(s);
+ specialRegisters_.add(s);
+ }
+ }
+
+ private void connectionClosedFailure() throws XAException { // throw an XAException XAER_RMFAIL, with a chained SqlException - closed
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (new SqlException(null, "Connection is Closed."),
+ exceptionsOnXA);
+ throwXAException(javax.transaction.xa.XAException.XAER_RMFAIL);
+ }
+
+ private String getXAFuncStr(int xaFunc) {
+ switch (xaFunc) {
+ case XAFUNC_COMMIT:
+ return XAFUNCSTR_COMMIT;
+ case XAFUNC_END:
+ return XAFUNCSTR_END;
+ case XAFUNC_FORGET:
+ return XAFUNCSTR_FORGET;
+ case XAFUNC_PREPARE:
+ return XAFUNCSTR_PREPARE;
+ case XAFUNC_RECOVER:
+ return XAFUNCSTR_RECOVER;
+ case XAFUNC_ROLLBACK:
+ return XAFUNCSTR_ROLLBACK;
+ case XAFUNC_START:
+ return XAFUNCSTR_START;
+ }
+ return XAFUNCSTR_NONE;
+ }
+
+ protected int xaRetValErrorAccumSQL(NetXACallInfo callInfo, int currentRC) {
+ int rc;
+ switch (callInfo.xaRetVal_) {
+ case XARETVAL_XAOK:
+ case XARETVAL_NODISSOCIATE:
+ rc = XAResource.XA_OK;
+ break;
+ case XARETVAL_XALCSNOTSUPP:
+ rc = XAResource.XA_OK;
+ break;
+ case XARETVAL_RBROLLBACK:
+ rc = XAException.XA_RBROLLBACK;
+ break;
+ case XARETVAL_RBOTHER:
+ rc = XAException.XA_RBOTHER;
+ break;
+ case XARETVAL_RBDEADLOCK:
+ rc = XAException.XA_RBDEADLOCK;
+ break;
+ case XARETVAL_RBPROTO:
+ rc = XAException.XA_RBPROTO;
+ break;
+ case XARETVAL_XAERPROTO:
+ rc = XAException.XAER_PROTO;
+ break;
+ case XARETVAL_XARDONLY:
+ rc = XAException.XA_RDONLY;
+ break;
+ case XARETVAL_XAHEURCOM:
+ rc = XAException.XA_HEURCOM;
+ break;
+ case XARETVAL_XAHEURRB:
+ rc = XAException.XA_HEURRB;
+ break;
+ case XARETVAL_XAERDUPID:
+ rc = XAException.XAER_DUPID;
+ break;
+ case XARETVAL_XAERNOTA:
+ rc = XAException.XAER_NOTA;
+ break;
+ case XARETVAL_XAERRMERR:
+ rc = XAException.XAER_RMERR;
+ break;
+ case XARETVAL_XAERRMFAIL:
+ rc = XAException.XAER_RMFAIL;
+ break;
+ case XARETVAL_XAERINVAL:
+ rc = XAException.XAER_INVAL;
+ break;
+ default:
+ rc = XAException.XAER_RMFAIL;
+ break;
+ }
+
+ if (rc != XAResource.XA_OK) { // error was detected
+ // create an SqlException to report this error within
+ String xaRetValStr = "Error executing a " +
+ getXAFuncStr(callInfo.xaFunction_) + ", " +
+ "Server returned " + getXAExceptionText(rc);
+ SqlException accumSql = new SqlException(conn_.netAgent_.logWriter_,
+ xaRetValStr, org.apache.derby.client.am.SqlState.undefined,
+ org.apache.derby.client.am.SqlCode.queuedXAError);
+ exceptionsOnXA = org.apache.derby.client.am.Utils.accumulateSQLException
+ (accumSql, exceptionsOnXA);
+
+ if (currentRC != XAResource.XA_OK) { // the rc passed into this function had an error also, prioritize error
+ if (currentRC < 0) { // rc passed in was a major error use it instead of current error
+ return currentRC;
+ }
+ }
+ }
+ return rc;
+ }
+
+ private String processLocalHost(String serverName) {
+ if (serverName.equalsIgnoreCase("localhost")) { // this is a localhost, find hostname
+ try {
+ InetAddress localhostNameIA = InetAddress.getLocalHost();
+ String localhostName = localhostNameIA.getHostName();
+ return localhostName;
+ } catch (SecurityException se) {
+ return serverName;
+ } catch (UnknownHostException ue) {
+ return serverName;
+ }
+ }
+ // not "localhost", return original server name
+ return serverName;
+ }
+
+ protected void removeXaresFromSameRMchain() {
+ // check all NetXAResources on the same RM for the NetXAResource to remove
+ try {
+ this.ignoreMe_ = true; // use the ignoreMe_ flag to indicate the
+ // XAResource to remove
+ NetXAResource prevXAResource = null;
+ NetXAResource currXAResource;
+ synchronized (xaResourceSameRMGroup_) { // make sure no one changes this vector list
+ currXAResource = (NetXAResource) xaResourceSameRMGroup_.elementAt(sameRMGroupIndex_);
+ while (currXAResource != null) { // is this the XAResource to remove?
+ if (currXAResource.ignoreMe_) { // this NetXAResource is the one to remove
+ if (prevXAResource != null) { // this XAResource is not first in chain, just move next to prev
+ prevXAResource.nextSameRM_ = currXAResource.nextSameRM_;
+ } else { // this XAResource is first in chain, just move next to root
+ xaResourceSameRMGroup_.set(sameRMGroupIndex_,
+ currXAResource.nextSameRM_);
+ }
+ return;
+ }
+ // this is not the NetXAResource to remove, try the next one
+ prevXAResource = currXAResource;
+ currXAResource = currXAResource.nextSameRM_;
+ }
+ }
+ } finally {
+ this.ignoreMe_ = false;
+ }
+ }
+
+
+ public void initForReuse() {
+ // add this new XAResource to the list of other XAResources for the Same RM
+ // first find out if there are any other XAResources for the same RM
+ // then check to make sure it is not already in the chain
+ synchronized (xaResourceSameRMGroup_) { // make sure no one changes this vector list
+ int groupCount = xaResourceSameRMGroup_.size();
+ int index = 0;
+ int firstFreeElement = -1;
+ NetXAResource xaResourceGroup = null;
+
+ for (; index < groupCount; ++index) { // check if this group is the same RM
+ xaResourceGroup = (NetXAResource) xaResourceSameRMGroup_.elementAt(index);
+ if (xaResourceGroup == null) { // this is a free element, save its index if first found
+ if (firstFreeElement == -1) { // first free element, save index
+ firstFreeElement = index;
+ }
+ continue; // go to next element
+ }
+ try {
+ if (xaResourceGroup.isSameRM(this)) { // it is the same RM add this XAResource to the chain if not there
+ NetXAResource nextXares = (NetXAResource)
+ xaResourceSameRMGroup_.elementAt(sameRMGroupIndex_);
+ while (nextXares != null) { // is this NetXAResource the one we are trying to add?
+ if (nextXares.equals(this)) { // the XAResource to be added already is in chain, don't add
+ break;
+ }
+ // Xid was not on that NetXAResource, try the next one
+ nextXares = nextXares.nextSameRM_;
+ }
+
+ if (nextXares == null) { // XAResource to be added is not in the chain already, add it
+ // add it at the head of the chain
+ sameRMGroupIndex_ = index;
+ this.nextSameRM_ = xaResourceGroup.nextSameRM_;
+ xaResourceGroup.nextSameRM_ = this;
+ }
+ return; // done
+ }
+ } catch (XAException xae) {
+ }
}
- if( nextXares == null )
- { // XAResource to be added is not in the chain already, add it
- // add it at the head of the chain
- sameRMGroupIndex_ = index;
- this.nextSameRM_ = xaResourceGroup.nextSameRM_;
- xaResourceGroup.nextSameRM_ = this;
+ // no other same RM was found, add this as first of new group
+ if (firstFreeElement == -1) { // no free element found, add new element to end
+ xaResourceSameRMGroup_.add(this);
+ sameRMGroupIndex_ = groupCount;
+ } else { // use first free element found
+ xaResourceSameRMGroup_.setElementAt(this, firstFreeElement);
+ sameRMGroupIndex_ = firstFreeElement;
}
- return; // done
- }
}
- catch( XAException xae )
- {}
- }
-
[... 15 lines stripped ...]