Search in sources :

Example 1 with ResourceCompletor

use of com.arjuna.ats.internal.jts.recovery.recoverycoordinators.ResourceCompletor in project narayana by jbosstm.

the class GenericRecoveryCoordinator method replay_completion.

/**
 * Respond to a replay_completion request for the RecoveryCoordinator
 * identified by parameter id.
 */
protected static Status replay_completion(RecoveryCoordinatorId id, Resource res) throws SystemException, NotPrepared {
    if (jtsLogger.logger.isDebugEnabled()) {
        jtsLogger.logger.debug("GenericRecoveryCoordinator(" + id._RCUid + ").replay_completion(" + (res != null ? "resource supplied)" : "null resource)"));
    }
    Status currentStatus = Status.StatusUnknown;
    /* 
	 * First check to see if the transaction is active by asking the 
	 * per-process contact.
	 * If alive, return the status reported by the
	 * transaction.  If not alive then try and recover the
	 * transaction from the intentions list.  
	 */
    boolean transactionActive = true;
    try {
        currentStatus = get_status(id._actionUid, id._originalProcessUid);
    } catch (Inactive e) {
        // original process is dead.
        transactionActive = false;
    }
    if (currentStatus == Status.StatusNoTransaction) {
        /*
	     * There is no intentions list, so the transaction either
	     * committed or rolled back. However, this routine is only
	     * ever called by replay_completion, which means that there
	     * is a resource (hopefully one which was participating in
	     * the transaction) that is in doubt as to the
	     * transaction's outcome. If the transaction had committed,
	     * then this resource would know of the outcome. Therefore,
	     * it must have rolled back!
	     */
        /*
	     * Unfortunately the last statement is wrong. There is a timing
	     * issue here: the resource recovery may be doing an upcall while
	     * the downcall (from coordinator recovery) is going on and
	     * removing the log. What can then happen is that a resource may
	     * see a commit folled by a rollback.
	     */
        currentStatus = Status.StatusRolledBack;
    }
    if (!transactionActive) {
        // original process is dead, so reasonable for us to try to
        // recover
        /*
	     * The RecoveredTransactionReplayer is a threaded object
	     * so we can get the status and return it while the
	     * replayer does the phase 2 commit in a new thread.  
	     */
        String tranType = ((id._isServerTransaction) ? ServerTransaction.typeName() : ArjunaTransactionImple.typeName());
        try {
            if (id._isServerTransaction && (StoreManager.getRecoveryStore().currentState(id._actionUid, ServerTransaction.typeName() + "/JCA") != StateStatus.OS_UNKNOWN)) {
                tranType = tranType + "/JCA";
            }
        } catch (ObjectStoreException e) {
        // Can't read store
        }
        com.arjuna.ats.internal.jts.recovery.transactions.RecoveredTransactionReplayer replayer = new com.arjuna.ats.internal.jts.recovery.transactions.RecoveredTransactionReplayer(id._actionUid, tranType);
        // this will cause the activatation attempt
        currentStatus = replayer.getStatus();
        if ((replayer.getRecoveryStatus() != com.arjuna.ats.internal.jts.recovery.transactions.RecoveryStatus.ACTIVATE_FAILED) && (res != null)) {
            if (jtsLogger.logger.isDebugEnabled()) {
                jtsLogger.logger.debug("GenericRecoveryCoordinator - swapping Resource for RC " + id._RCUid);
            }
            replayer.swapResource(id._RCUid, res);
        }
        if (replayer.getRecoveryStatus() != com.arjuna.ats.internal.jts.recovery.transactions.RecoveryStatus.ACTIVATE_FAILED) {
            replayer.replayPhase2();
        } else {
            replayer.tidyup();
            /*
		 * The transaction didn't activate so we have a
		 * rollback situation but we can't rollback the
		 * resource that we have been given through the
		 * intentions list but we can issue rollback
		 * directly. This is configurable through the System
		 * properties.
		 */
            currentStatus = Status.StatusRolledBack;
        }
    }
    if (currentStatus == Status.StatusRolledBack) {
        if (_issueRecoveryRollback) {
            ResourceCompletor resourceCompletor = new ResourceCompletor(res, ResourceCompletor.ROLLBACK);
            resourceCompletor.start();
        }
    }
    if (currentStatus == Status.StatusActive)
        throw new NotPrepared();
    return currentStatus;
}
Also used : StateStatus(com.arjuna.ats.arjuna.objectstore.StateStatus) Status(org.omg.CosTransactions.Status) ObjectStoreException(com.arjuna.ats.arjuna.exceptions.ObjectStoreException) ResourceCompletor(com.arjuna.ats.internal.jts.recovery.recoverycoordinators.ResourceCompletor) NotPrepared(org.omg.CosTransactions.NotPrepared) Inactive(org.omg.CosTransactions.Inactive)

Aggregations

ObjectStoreException (com.arjuna.ats.arjuna.exceptions.ObjectStoreException)1 StateStatus (com.arjuna.ats.arjuna.objectstore.StateStatus)1 ResourceCompletor (com.arjuna.ats.internal.jts.recovery.recoverycoordinators.ResourceCompletor)1 Inactive (org.omg.CosTransactions.Inactive)1 NotPrepared (org.omg.CosTransactions.NotPrepared)1 Status (org.omg.CosTransactions.Status)1