Search in sources :

Example 6 with XAXactId

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);
}
Also used : XAXactId(org.apache.derby.iapi.store.access.xa.XAXactId) XAException(javax.transaction.xa.XAException) SQLException(java.sql.SQLException)

Example 7 with XAXactId

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;
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) XAXactId(org.apache.derby.iapi.store.access.xa.XAXactId) XAException(javax.transaction.xa.XAException) SQLException(java.sql.SQLException)

Example 8 with XAXactId

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;
        }
    }
}
Also used : XAXactId(org.apache.derby.iapi.store.access.xa.XAXactId) XAException(javax.transaction.xa.XAException) XAResourceManager(org.apache.derby.iapi.store.access.xa.XAResourceManager) SQLException(java.sql.SQLException) ContextManager(org.apache.derby.iapi.services.context.ContextManager)

Example 9 with XAXactId

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);
        }
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) XAXactId(org.apache.derby.iapi.store.access.xa.XAXactId) ContextService(org.apache.derby.iapi.services.context.ContextService) XAException(javax.transaction.xa.XAException) XAResourceManager(org.apache.derby.iapi.store.access.xa.XAResourceManager) SQLException(java.sql.SQLException) ContextManager(org.apache.derby.iapi.services.context.ContextManager)

Aggregations

XAXactId (org.apache.derby.iapi.store.access.xa.XAXactId)9 XAException (javax.transaction.xa.XAException)7 SQLException (java.sql.SQLException)5 ContextManager (org.apache.derby.iapi.services.context.ContextManager)4 XAResourceManager (org.apache.derby.iapi.store.access.xa.XAResourceManager)4 StandardException (org.apache.derby.shared.common.error.StandardException)4 ContextService (org.apache.derby.iapi.services.context.ContextService)3 ArrayList (java.util.ArrayList)1 AccessFactory (org.apache.derby.iapi.store.access.AccessFactory)1