📄 netxaresource.java
字号:
/* Derby - Class org.apache.derby.client.net.NetXAResource Copyright (c) 2003, 2005 The Apache Software Foundation or its licensors, where applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*//********************************************************************** * * * Component Name = * * Package Name = org.apache.derby.client.net * * Descriptive Name = class implements XAResource * * Status = New code * * Function = Handle XA methods * * List of Classes * - NetXAResource * * Restrictions : None * **********************************************************************/package org.apache.derby.client.net;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(); // 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; 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 // TODO: 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 // TODO: 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, 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_.isPhysicalConnClosed()) { connectionClosedFailure(); } // update the XACallInfo NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_]; callInfo.xaFlags_ = (onePhase ? XAResource.TMONEPHASE : XAResource.TMNOFLAGS); callInfo.xid_ = xid; callInfo.xaResource_ = this; callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL try { netAgent.beginWriteChainOutsideUOW(); netAgent.netConnectionRequest_.writeXaCommit(conn_, xid); netAgent.flowOutsideUOW(); netAgent.netConnectionReply_.readXaCommit(conn_); if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it callInfo.xaFunction_ = XAFUNC_COMMIT; rc = xaRetValErrorAccumSQL(callInfo, rc); callInfo.xaRetVal_ = XAResource.XA_OK; // 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_.isPhysicalConnClosed()) { connectionClosedFailure(); } NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_]; callInfo.setReadOnlyTransactionFlag(conn_.readOnlyTransaction_); callInfo.xaFlags_ = flags; callInfo.xid_ = xid; callInfo.xaResource_ = this; callInfo.xaRetVal_ = XAResource.XA_OK; // 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_ != XAResource.XA_OK) { // xaRetVal has possible error, format it callInfo.xaFunction_ = XAFUNC_END; rc = xaRetValErrorAccumSQL(callInfo, rc); callInfo.xaRetVal_ = XAResource.XA_OK; // 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_T0_NOT_ASSOCIATED); } } /** * 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_.isPhysicalConnClosed()) { connectionClosedFailure(); } NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_]; callInfo.xid_ = xid; callInfo.xaResource_ = this; callInfo.xaRetVal_ = XAResource.XA_OK; // 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_ != XAResource.XA_OK) { // xaRetVal has possible error, format it callInfo.xaFunction_ = XAFUNC_FORGET; rc = xaRetValErrorAccumSQL(callInfo, rc); callInfo.xaRetVal_ = XAResource.XA_OK; // 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_.isPhysicalConnClosed()) { 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -