use of org.apache.derby.iapi.store.access.xa.XAXactId in project derby by apache.
the class EmbedXAResource method end.
/**
* Ends the work performed on behalf of a transaction branch. The resource
* manager disassociates 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
*
* @exception XAException An error has occurred.
* Possible XAException values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA,
* XAER_INVAL, XAER_PROTO, or XA_RB*.
*/
public final synchronized void end(Xid xid, int flags) throws XAException {
checkXAActive();
try {
// isolation level.
if (con.currentConnectionHandle != null)
con.currentConnectionHandle.getIsolationUptoDate();
} catch (SQLException sqle) {
throw wrapInXAException(sqle);
}
// ensure immtable and correct equals method.
XAXactId xid_im = new XAXactId(xid);
boolean endingCurrentXid = false;
// must match the Xid from start()
if (currentXid != null) {
if (!currentXid.equals(xid_im))
throw new XAException(XAException.XAER_PROTO);
endingCurrentXid = true;
}
XATransactionState tranState = getTransactionState(xid_im);
if (tranState == null)
throw new XAException(XAException.XAER_NOTA);
boolean rollbackOnly = tranState.end(this, flags, endingCurrentXid);
// where we are not ending the current XID.
if (endingCurrentXid) {
currentXid = null;
con.realConnection = null;
}
if (rollbackOnly)
throw new XAException(tranState.rollbackOnlyCode);
}
use of org.apache.derby.iapi.store.access.xa.XAXactId in project derby by apache.
the class EmbedXAResource method start.
/**
* Start work on behalf of a transaction branch specified in xid If TMJOIN
* is specified, the start is for joining a transaction previously seen by
* the resource manager. If TMRESUME is specified, the start is to resume
* a suspended transaction specified in the parameter xid. If neither
* TMJOIN nor TMRESUME is specified and the transaction specified by xid
* has previously been seen by the resource manager, the resource manager
* throws the XAException exception with XAER_DUPID error code.
*
* @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 final synchronized void start(Xid xid, int flags) throws XAException {
checkXAActive();
// JDBC 3.0 section 12.3 - One transaction associated with a XAConnection
if (currentXid != null)
throw new XAException(XAException.XAER_PROTO);
// ensure immtable and correct equals method.
XAXactId xid_im = new XAXactId(xid);
XATransactionState tranState = getTransactionState(xid_im);
switch(flags) {
case XAResource.TMNOFLAGS:
if (tranState != null)
throw new XAException(XAException.XAER_DUPID);
try {
if (con.realConnection == null) {
con.openRealConnection();
if (con.currentConnectionHandle != null) {
// since this is a new connection, set its complete
// state according to the application's Connection
// handle view of the world.
con.currentConnectionHandle.setState(true);
con.realConnection.setApplicationConnection(con.currentConnectionHandle);
}
} else {
// auto commit mode.
if (con.currentConnectionHandle != null) {
if (con.currentConnectionHandle.getAutoCommit())
con.currentConnectionHandle.rollback();
}
if (!con.realConnection.transactionIsIdle())
throw new XAException(XAException.XAER_OUTSIDE);
if (con.currentConnectionHandle != null) {
// It is possible that the isolation level state
// in connection handle has gotten out of sync
// with the real isolation level. This can happen
// if SLQ instead of JDBC api has been used to set
// the isolation level. The code below will check
// if isolation was set using JDBC or SQL and if
// yes, then it will update the isolation state
// in BrokeredConnection with EmbedConnection's
// isolation level.
con.currentConnectionHandle.getIsolationUptoDate();
// we have a current handle so we need to keep
// the connection state of the current connection.
con.currentConnectionHandle.setState(true);
// At the local to global transition we need
// to discard and close any open held result
// sets, a rollback will do this.
con.realConnection.rollback();
} else {
con.resetRealConnection();
}
}
// Global connections are always in auto commit false mode.
con.realConnection.setAutoCommit(false);
// and holdability false (cannot hold cursors across
// XA transactions.
con.realConnection.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
getLanguageConnectionContext(con.realConnection).getTransactionExecute().createXATransactionFromLocalTransaction(xid_im.getFormatId(), xid_im.getGlobalTransactionId(), xid_im.getBranchQualifier());
} catch (StandardException se) {
throw wrapInXAException(se);
} catch (SQLException sqle) {
throw wrapInXAException(sqle);
}
tranState = new XATransactionState(getContextManager(con.realConnection), con.realConnection, this, xid_im);
if (!ra.addConnection(xid_im, tranState))
throw new XAException(XAException.XAER_DUPID);
currentXid = xid_im;
// it means that transaction timeout is disabled.
if (timeoutSeconds != Integer.MAX_VALUE) {
// Find out the value of the transaction timeout
long timeoutMillis;
if (timeoutSeconds > 0) {
timeoutMillis = 1000 * timeoutSeconds;
} else {
timeoutMillis = getDefaultXATransactionTimeout();
}
// it was specified as a default transaction timeout
if (timeoutMillis > 0) {
tranState.scheduleTimeoutTask(timeoutMillis);
}
}
break;
case XAResource.TMRESUME:
case XAResource.TMJOIN:
if (tranState == null)
throw new XAException(XAException.XAER_NOTA);
tranState.start(this, flags);
if (tranState.conn != con.realConnection) {
if (con.realConnection != null) {
if (!con.realConnection.transactionIsIdle())
throw new XAException(XAException.XAER_OUTSIDE);
// local mode.
try {
if (con.currentConnectionHandle != null) {
con.currentConnectionHandle.getIsolationUptoDate();
}
} catch (SQLException sqle) {
throw wrapInXAException(sqle);
}
closeUnusedConnection(con.realConnection);
}
con.realConnection = tranState.conn;
if (con.currentConnectionHandle != null) {
try {
// only reset the non-transaction specific
// Connection state.
con.currentConnectionHandle.setState(false);
con.realConnection.setApplicationConnection(con.currentConnectionHandle);
} catch (SQLException sqle) {
throw wrapInXAException(sqle);
}
}
}
break;
default:
throw new XAException(XAException.XAER_INVAL);
}
currentXid = xid_im;
}
use of org.apache.derby.iapi.store.access.xa.XAXactId in project derby by apache.
the class EmbedXAResource method prepare.
/**
* 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.
*
* @exception XAException An error has occurred. Possible exception values
* are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or
* XAER_PROTO.
*/
public final synchronized int prepare(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);
// cannot prepare in doubt transactions
throw new XAException(XAException.XAER_PROTO);
}
synchronized (tranState) {
checkUserCredentials(tranState.creatingResource);
// any XAResource.
switch(tranState.associationState) {
case XATransactionState.T0_NOT_ASSOCIATED:
break;
case XATransactionState.TRO_FAIL:
throw new XAException(tranState.rollbackOnlyCode);
default:
throw new XAException(XAException.XAER_PROTO);
}
if (tranState.suspendedList != null && tranState.suspendedList.size() != 0)
throw new XAException(XAException.XAER_PROTO);
if (tranState.isPrepared)
throw new XAException(XAException.XAER_PROTO);
try {
int ret = tranState.xa_prepare();
if (ret == XATransactionController.XA_OK) {
tranState.isPrepared = true;
return XAResource.XA_OK;
} else {
returnConnectionToResource(tranState, xid_im);
if (SanityManager.DEBUG) {
if (con.realConnection != null) {
SanityManager.ASSERT(con.realConnection.transactionIsIdle(), "real connection should have been idle." + "tranState = " + tranState + "ret = " + ret + "con.realConnection = " + con.realConnection);
}
}
return XAResource.XA_RDONLY;
}
} catch (SQLException sqle) {
XAException xe = wrapInXAException(sqle);
if (ExceptionUtil.isDeferredConstraintViolation(sqle.getSQLState())) {
// We are rolling back
returnConnectionToResource(tranState, xid_im);
}
throw xe;
}
}
}
use of org.apache.derby.iapi.store.access.xa.XAXactId in project derby by apache.
the class EmbedXAResource method commit.
/**
* Commit the global transaction specified by xid.
* @param xid A global transaction identifier
* @param onePhase If true, the resource manager should use a one-phase
* commit protocol to commit the work done on behalf of xid.
*
* @exception XAException An error has occurred. Possible XAExceptions are
* XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR,
* XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
* <P>If the resource manager did not commit the transaction and
* the paramether onePhase is set to true, the resource manager
* may throw one of the XA_RB* exceptions. Upon return, the
* resource manager has rolled back the branch's work and has
* released all held resources.
*/
public final synchronized void commit(Xid xid, boolean onePhase) 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 = getContextService();
csf.setCurrentContextManager(inDoubtCM);
try {
rm.commit(inDoubtCM, xid_im, onePhase);
// close the connection/transaction since it can never
// be used again. DERBY-4856 No extended diagnostic information needed.
inDoubtCM.cleanupOnError(StandardException.closeException(), false);
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, con.isActive());
throw wrapInXAException(se);
} finally {
csf.resetCurrentContextManager(inDoubtCM);
}
}
synchronized (tranState) {
checkUserCredentials(tranState.creatingResource);
// any XAResource.
switch(tranState.associationState) {
case XATransactionState.T0_NOT_ASSOCIATED:
break;
case XATransactionState.TRO_FAIL:
throw new XAException(tranState.rollbackOnlyCode);
default:
throw new XAException(XAException.XAER_PROTO);
}
if (tranState.suspendedList != null && tranState.suspendedList.size() != 0)
throw new XAException(XAException.XAER_PROTO);
if (tranState.isPrepared == onePhase)
throw new XAException(XAException.XAER_PROTO);
try {
tranState.xa_commit(onePhase);
} catch (SQLException sqle) {
throw wrapInXAException(sqle);
} finally {
returnConnectionToResource(tranState, xid_im);
}
}
}
Aggregations