📄 embedxaconnection.java
字号:
*/ public final synchronized void rollback(Xid xid) throws XAException { checkXAActive(); // ensure immtable and correct equals method. XAXactId xid_im = new XAXactId(xid); XATransactionState tranState = getTransactionState(xid_im); if (tranState == null) { XAResourceManager rm = ra.getXAResourceManager(); ContextManager inDoubtCM = rm.find(xid); // RM also does not know about this xid. if (inDoubtCM == null) throw new XAException(XAException.XAER_NOTA); ContextService csf = ContextService.getFactory(); csf.setCurrentContextManager(inDoubtCM); try { rm.rollback(inDoubtCM, xid_im); // close the connection/transaction since it can never be used again. inDoubtCM.cleanupOnError(StandardException.closeException()); return; } catch (StandardException se) { // The rm threw an exception, clean it up in the approprate // context. There is no transactionResource to handle the // exception for us. inDoubtCM.cleanupOnError(se); throw wrapInXAException(se); } finally { csf.resetCurrentContextManager(inDoubtCM); } } synchronized (tranState) { // Check the transaction is no associated with // any XAResource. switch (tranState.associationState) { case XATransactionState.T0_NOT_ASSOCIATED: case XATransactionState.TRO_FAIL: break; default: throw new XAException(XAException.XAER_PROTO); } if (tranState.suspendedList != null && tranState.suspendedList.size() != 0) throw new XAException(XAException.XAER_PROTO); checkUserCredentials(tranState.creatingResource); try { tranState.conn.xa_rollback(); } catch (SQLException sqle) { throw wrapInXAException(sqle); } finally { returnConnectionToResource(tranState, xid_im); } } } /** 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 throw the appropriate XAException. @exception XAException An error has occurred. Possible values are XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO. */ public final synchronized Xid[] recover(int flag) throws XAException { checkXAActive(); try { return ra.getXAResourceManager().recover(flag); } catch (StandardException se) { throw wrapInXAException(se); } } /** Tell the resource manager to forget about a heuristically 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 final synchronized void forget(Xid xid) throws XAException { checkXAActive(); // ensure immtable and correct equals method. XAXactId xid_im = new XAXactId(xid); XATransactionState tranState = getTransactionState(xid_im); if (tranState == null) { XAResourceManager rm = ra.getXAResourceManager(); ContextManager inDoubtCM = rm.find(xid); // RM also does not know about this xid. if (inDoubtCM == null) throw new XAException(XAException.XAER_NOTA); ContextService csf = ContextService.getFactory(); csf.setCurrentContextManager(inDoubtCM); try { rm.forget(inDoubtCM, xid_im); // close the connection/transaction since it can never be used again. inDoubtCM.cleanupOnError(StandardException.closeException()); return; } catch (StandardException se) { // The rm threw an exception, clean it up in the approprate // context. There is no transactionResource to handle the // exception for us. inDoubtCM.cleanupOnError(se); throw wrapInXAException(se); } finally { csf.resetCurrentContextManager(inDoubtCM); } } throw new XAException(tranState.isPrepared ? XAException.XAER_NOTA : XAException.XAER_PROTO); } /** This method is called to determine if the resource manager instance represented by the target object is the same as the resouce manager instance represented by the parameter xares. @param xares An XAResource object whose resource manager instance is to be compared with the resource manager instance of the target object. @return true if it's the same RM instance; otherwise false. @exception XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL. */ public final synchronized boolean isSameRM(XAResource xares) throws XAException { checkXAActive(); if (xares instanceof EmbedXAConnection) { return ra == ((EmbedXAConnection) xares).ra; } return false; } /** Obtain the current transaction timeout value set for this XAResource instance. If XAResource.setTransactionTimeout 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 setTransactionTimeout call is returned. @return the transaction timeout value in seconds. */ public int getTransactionTimeout() { return 0; } /** Set the current transaction timeout value for this XAResource instance. Once set, this timeout value is effective until setTransactionTimeout is invoked again with a different value. To reset the timeout value to the default value used by the resource manager, set the value to zero. If the timeout operation is performed successfully, the method returns true; otherwise false. If a resource manager does not support transaction timeout value to be set explicitly, this method returns false. @param seconds the transaction timeout value in seconds. @return true if transaction timeout value is set successfully; otherwise false. @exception XAException - An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL. */ public boolean setTransactionTimeout(int seconds) { return false; } /* ** BrokeredConnectionControl api */ /** Allow control over setting auto commit mode. */ public void checkAutoCommit(boolean autoCommit) throws SQLException { if (autoCommit && (currentXid != null)) throw Util.generateCsSQLException(SQLState.CANNOT_AUTOCOMMIT_XA); super.checkAutoCommit(autoCommit); } /** Are held cursors allowed. If the connection is attached to a global transaction then downgrade the result set holdabilty to CLOSE_CURSORS_AT_COMMIT if downgrade is true, otherwise throw an exception. If the connection is in a local transaction then the passed in holdabilty is returned. */ public int checkHoldCursors(int holdability, boolean downgrade) throws SQLException { if (holdability == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT) { if (currentXid != null) { if (!downgrade) throw Util.generateCsSQLException(SQLState.CANNOT_HOLD_CURSOR_XA); holdability = JDBC30Translation.CLOSE_CURSORS_AT_COMMIT; } } return super.checkHoldCursors(holdability, downgrade); } /** Allow control over creating a Savepoint (JDBC 3.0) */ public void checkSavepoint() throws SQLException { if (currentXid != null) throw Util.generateCsSQLException(SQLState.CANNOT_ROLLBACK_XA); super.checkSavepoint(); } /** Allow control over calling rollback. */ public void checkRollback() throws SQLException { if (currentXid != null) throw Util.generateCsSQLException(SQLState.CANNOT_ROLLBACK_XA); super.checkRollback(); } /** Allow control over calling commit. */ public void checkCommit() throws SQLException { if (currentXid != null) throw Util.generateCsSQLException(SQLState.CANNOT_COMMIT_XA); super.checkCommit(); } public Connection getConnection() throws SQLException { Connection handle; // Is this just a local transaction? if (currentXid == null) { handle = super.getConnection(); } else { if (currentConnectionHandle != null) { // this can only happen if someone called start(Xid), // getConnection, getConnection (and we are now the 2nd // getConnection call). // Cannot yank a global connection away like, I don't think... throw Util.generateCsSQLException( SQLState.CANNOT_CLOSE_ACTIVE_XA_CONNECTION); } handle = getNewCurrentConnectionHandle(); } currentConnectionHandle.syncState(); return handle; } /** Wrap and control a Statement */ public Statement wrapStatement(Statement s) throws SQLException { XAStatementControl sc = new XAStatementControl(this, s); return sc.applicationStatement; } /** Wrap and control a PreparedStatement */ public PreparedStatement wrapStatement(PreparedStatement ps, String sql, Object generatedKeys) throws SQLException { XAStatementControl sc = new XAStatementControl(this, ps, sql, generatedKeys); return (PreparedStatement) sc.applicationStatement; } /** Wrap and control a PreparedStatement */ public CallableStatement wrapStatement(CallableStatement cs, String sql) throws SQLException { XAStatementControl sc = new XAStatementControl(this, cs, sql); return (CallableStatement) sc.applicationStatement; } /** Override getRealConnection to create a a local connection when we are not associated with an XA transaction. This can occur if the application has a Connection object (conn) and the following sequence occurs. conn = xac.getConnection(); xac.start(xid, ...) // do work with conn xac.end(xid, ...); // do local work with conn // need to create new connection here. */ public EngineConnection getRealConnection() throws SQLException { EngineConnection rc = super.getRealConnection(); if (rc != null) return rc; openRealConnection(); // a new Connection, set its state according to the application's Connection handle currentConnectionHandle.setState(true); return realConnection; } /* ** Class specific methods */ private XATransactionState getTransactionState(XAXactId xid_im) { return (XATransactionState) ra.findConnection(xid_im); } /** Map a SQL exception to appropriate XAException. Return the mapped XAException. */ private static XAException wrapInXAException(SQLException se) { // Map interesting exceptions to XAException String sqlstate = se.getSQLState(); String message = se.getMessage(); XAException xae; if (sqlstate == null) { // no idea what was wrong, throw non-descript error. if (message != null) xae = new XAException(message); else xae = new XAException(XAException.XAER_RMERR); } else if (sqlstate.equals(StandardException.getSQLStateFromIdentifier(SQLState.STORE_XA_XAER_DUPID))) xae = new XAException(XAException.XAER_DUPID); else if (sqlstate.equals(StandardException.getSQLStateFromIdentifier(SQLState.STORE_XA_PROTOCOL_VIOLATION))) xae = new XAException(XAException.XA_RBPROTO); else if (sqlstate.equals(SQLState.DEADLOCK)) xae = new XAException(XAException.XA_RBDEADLOCK); else if (sqlstate.equals(SQLState.LOCK_TIMEOUT)) xae = new XAException(XAException.XA_RBTIMEOUT); else if (message != null) xae = new XAException(message); else xae = new XAException(XAException.XAER_RMERR); if (JVMInfo.JDK_ID >= JVMInfo.J2SE_14) xae.initCause(se); return xae; } /** Map a Standard exception to appropriate XAException. Return the mapped XAException. */ private static XAException wrapInXAException(StandardException se) { return wrapInXAException(TransactionResourceImpl.wrapInSQLException((SQLException) null, se)); } void removeXATransaction(XAXactId xid_im) { XATransactionState tranState = (XATransactionState) ra.removeConnection(xid_im); if (tranState != null) tranState.popMe(); } /** Return an underlying connection object back to its XAResource if possible. If not close the connection. */ private void returnConnectionToResource(XATransactionState tranState, XAXactId xid_im) { removeXATransaction(xid_im); synchronized (tranState) { // global transaction is over. tranState.associationState = XATransactionState.TC_COMPLETED; tranState.notifyAll(); EmbedConnection conn = tranState.conn; // already set in its own resource // or can it be returned to its original resource? if ((tranState.creatingResource.realConnection == conn) || (tranState.creatingResource.realConnection == null)) { tranState.creatingResource.realConnection = conn; BrokeredConnection handle = tranState.creatingResource.currentConnectionHandle; conn.setApplicationConnection(handle); if (handle != null) { try { handle.setState(true); } catch (SQLException sqle) { // couldn't reset the connection closeUnusedConnection(tranState.conn); tranState.creatingResource.realConnection = null; } } return; } } // nowhere to place it, close it. closeUnusedConnection(tranState.conn); } private void checkXAActive() throws XAException { try { checkActive(); } catch (SQLException sqle) { throw wrapInXAException(sqle); } } private void checkUserCredentials(EmbedXAConnection original) throws XAException { if (original == this) return; if (original.getPassword().equals(getPassword()) && (original.getUsername().equals(getUsername()))) return; throw new XAException(XAException.XA_RBINTEGRITY); } /** Close an underlying connection object when there is no active XAResource to hand it to. */ private static void closeUnusedConnection(EmbedConnection conn) { if (conn != null) { try { conn.close(); } catch (SQLException sqle) { } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -