Search in sources :

Example 1 with Header

use of com.arjuna.ats.internal.arjuna.Header in project narayana by jbosstm.

the class BasicActionFinalizer method save_state.

/*
      * Can be done at any time (Is this correct?)
      */
/**
 * Redefined version of save_state and restore_state from StateManager.
 *
 * Normal operation (no crashes):
 *
 * BasicAction.save_state is called after a successful prepare. This causes
 * and BasicAction object to be saved in the object store. This object
 * contains primarily the "intentions list" of the BasicAction. After
 * successfully completing phase 2 of the commit protocol, the BasicAction
 * object is deleted from the store.
 *
 * Failure cases:
 *
 * If a server crashes after successfully preparing, then upon recovery the
 * action must be resolved (either committed or aborted) depending upon
 * whether the co-ordinating atomic action committed or aborted. Upon server
 * recovery, the crash recovery mechanism detects ServerBasicAction objects
 * in the object store and attempts to activate the BasicAction object of
 * the co-ordinating action. If this is successful then the SAA is committed
 * else aborted.
 *
 * If, when processing phase 2 of the commit protocol, the co-ordinator
 * experiences a failure to commit from one of the records then the
 * BasicAction object is NOT deleted. It is rewritten when a new state which
 * contains a list of the records that failed during phase 2 commit. This
 * list is called the "failedList".
 *
 * The crash recovery manager will detect local BasicAction objects in
 * addition to SAA objects in the objectstore. An attempt will be made to
 * commit these actions. If the action contained a call to a now dead
 * server, this action can never be resolved and the AA object can never be
 * removed. However, if the action is purely local then after the processing
 * is complete the removed by crash recovery.
 *
 * @return <code>true</code> if successful, <code>false</code>
 *         otherwise.
 */
public boolean save_state(OutputObjectState os, int ot) {
    if (tsLogger.logger.isTraceEnabled()) {
        tsLogger.logger.trace("BasicAction::save_state ()");
    }
    try {
        packHeader(os, new Header(get_uid(), Utility.getProcessUid()));
        os.packBoolean(pastFirstParticipant);
    } catch (IOException e) {
        return false;
    }
    /*
           * In a presumed abort scenario, this routine is called: a) After a
           * successful prepare - to save the intentions list. b) After a failure
           * during phase 2 of commit - to overwrite the intentions list by the
           * failedList.
           *
           * If we're using presumed nothing, then it could be called: a) Whenever
           * a participant is registered.
           */
    RecordList listToSave = null;
    boolean res = true;
    if ((failedList != null) && (failedList.size() > 0)) {
        listToSave = failedList;
    } else {
        listToSave = preparedList;
    }
    AbstractRecord first = ((listToSave != null) ? listToSave.getFront() : null);
    AbstractRecord temp = first;
    boolean havePacked = ((listToSave == null) ? false : true);
    while ((res) && (temp != null)) {
        listToSave.putRear(temp);
        if (tsLogger.logger.isTraceEnabled()) {
            tsLogger.logger.trace("BasicAction::save_state - next record to pack is a " + temp.typeIs() + " record " + temp.type() + " should save it? = " + temp.doSave());
        }
        if (temp.doSave()) {
            res = true;
            try {
                if (tsLogger.logger.isTraceEnabled()) {
                    tsLogger.logger.trace("Packing a " + temp.typeIs() + " record");
                }
                os.packInt(temp.typeIs());
                res = temp.save_state(os, ot);
            } catch (IOException e) {
                res = false;
            }
        }
        temp = listToSave.getFront();
        if (temp == first) {
            listToSave.putFront(temp);
            temp = null;
        }
    }
    if (res && (os.notempty() || !havePacked)) {
        try {
            if (tsLogger.logger.isTraceEnabled()) {
                tsLogger.logger.trace("Packing a NONE_RECORD");
            }
            os.packInt(RecordType.NONE_RECORD);
        } catch (IOException e) {
            res = false;
        }
    }
    if (res) {
        // Now deal with anything on the heuristic list!
        int hSize = ((heuristicList == null) ? 0 : heuristicList.size());
        try {
            os.packInt(hSize);
        } catch (IOException e) {
            res = false;
        }
        if (res && (hSize > 0)) {
            first = heuristicList.getFront();
            temp = first;
            while (res && (temp != null)) {
                heuristicList.putRear(temp);
                if (temp.doSave()) {
                    res = true;
                    try {
                        if (tsLogger.logger.isTraceEnabled()) {
                            tsLogger.logger.trace("HeuristicList - packing a " + temp.typeIs() + " record");
                        }
                        os.packInt(temp.typeIs());
                        res = temp.save_state(os, ot);
                    } catch (IOException e) {
                        res = false;
                    }
                }
                temp = heuristicList.getFront();
                if (temp == first) {
                    heuristicList.putFront(temp);
                    temp = null;
                }
            }
            if (res && os.notempty()) {
                try {
                    if (tsLogger.logger.isTraceEnabled()) {
                        tsLogger.logger.trace("HeuristicList - packing a NONE_RECORD");
                    }
                    os.packInt(RecordType.NONE_RECORD);
                } catch (IOException e) {
                    res = false;
                }
            }
        }
    }
    if (res && os.notempty()) {
        try {
            if (tsLogger.logger.isTraceEnabled()) {
                tsLogger.logger.trace("Packing action status of " + ActionStatus.stringForm(actionStatus));
            }
            os.packInt(actionStatus);
            // why pack since only top-level?
            os.packInt(actionType);
            // can we optimize?
            os.packInt(heuristicDecision);
        } catch (IOException e) {
            res = false;
        }
    }
    return res;
}
Also used : Header(com.arjuna.ats.internal.arjuna.Header) IOException(java.io.IOException)

Example 2 with Header

use of com.arjuna.ats.internal.arjuna.Header in project narayana by jbosstm.

the class BasicActionFinalizer method restore_state.

/**
 * This assumes the various lists are zero length when it is called.
 *
 * @return <code>true</code> if successful, <code>false</code>
 *         otherwise.
 */
public boolean restore_state(InputObjectState os, int ot) {
    if (tsLogger.logger.isTraceEnabled()) {
        tsLogger.logger.trace("BasicAction::restore_state ()");
    }
    createPreparedLists();
    boolean res = true;
    int record_type = RecordType.NONE_RECORD;
    int tempActionStatus = ActionStatus.INVALID;
    int tempActionType = ActionType.TOP_LEVEL;
    int tempHeuristicDecision = TwoPhaseOutcome.PREPARE_OK;
    try {
        Header hdr = new Header();
        unpackHeader(os, hdr);
        pastFirstParticipant = os.unpackBoolean();
    } catch (IOException e) {
        return false;
    }
    try {
        record_type = os.unpackInt();
        if (tsLogger.logger.isTraceEnabled()) {
            tsLogger.logger.trace("Unpacked a " + record_type + " record");
        }
    } catch (IOException e) {
        res = false;
    }
    while ((res) && (record_type != RecordType.NONE_RECORD)) {
        AbstractRecord record = AbstractRecord.create(record_type);
        if (record == null) {
            tsLogger.i18NLogger.warn_coordinator_BasicAction_21(Integer.toString(record_type));
            res = false;
        } else
            res = (record.restore_state(os, ot) && preparedList.insert(record));
        if (res) {
            try {
                record_type = os.unpackInt();
                if (tsLogger.logger.isTraceEnabled()) {
                    tsLogger.logger.trace("Unpacked a " + record_type + " record");
                }
            } catch (IOException e) {
                res = false;
            }
        }
    }
    // Now deal with the heuristic list!
    int hSize = 0;
    if (res) {
        try {
            hSize = os.unpackInt();
            if (tsLogger.logger.isTraceEnabled()) {
                tsLogger.logger.trace("HeuristicList - Unpacked heuristic list size of " + hSize);
            }
        } catch (IOException e) {
            res = false;
        }
    }
    if (hSize > 0) {
        tsLogger.logger.warn("Transaction " + get_uid() + " has " + hSize + " heuristic participant(s)!");
        try {
            record_type = os.unpackInt();
            if (tsLogger.logger.isTraceEnabled()) {
                tsLogger.logger.trace("HeuristicList - Unpacked a " + record_type + " record");
            }
        } catch (IOException e) {
            res = false;
        }
        while ((res) && (record_type != RecordType.NONE_RECORD)) {
            AbstractRecord record = AbstractRecord.create(record_type);
            try {
                res = (record.restore_state(os, ot) && heuristicList.insert(record));
                record_type = os.unpackInt();
                tsLogger.logger.warn("Transaction " + get_uid() + " restored heuristic participant " + record);
                if (tsLogger.logger.isTraceEnabled()) {
                    tsLogger.logger.trace("HeuristicList - Unpacked a " + record_type + " record");
                }
            } catch (IOException e) {
                res = false;
            } catch (final NullPointerException ex) {
                tsLogger.i18NLogger.warn_coordinator_norecordfound(Integer.toString(record_type));
                res = false;
            }
        }
    }
    if (res) {
        try {
            tempActionStatus = os.unpackInt();
            tempActionType = os.unpackInt();
            tempHeuristicDecision = os.unpackInt();
        } catch (IOException e) {
            tsLogger.i18NLogger.warn_coordinator_BasicAction_24();
            res = false;
        }
    }
    if (res) {
        if (tsLogger.logger.isTraceEnabled()) {
            tsLogger.logger.trace("Restored action status of " + ActionStatus.stringForm(tempActionStatus) + " " + Integer.toString(tempActionStatus));
            tsLogger.logger.trace("Restored action type " + ((tempActionType == ActionType.NESTED) ? "Nested" : "Top-level") + " " + Integer.toString(tempActionType));
            tsLogger.logger.trace(" Restored heuristic decision of " + TwoPhaseOutcome.stringForm(tempHeuristicDecision) + " " + Integer.toString(tempHeuristicDecision));
        }
        actionStatus = tempActionStatus;
        actionType = tempActionType;
        heuristicDecision = tempHeuristicDecision;
        savedIntentionList = true;
    }
    return res;
}
Also used : Header(com.arjuna.ats.internal.arjuna.Header) IOException(java.io.IOException)

Example 3 with Header

use of com.arjuna.ats.internal.arjuna.Header in project narayana by jbosstm.

the class RecoveredTransactionalObject method findHoldingTransaction.

/**
 * Determine which transaction got this into uncommitted state return true
 * if there is such a transaction
 */
private final boolean findHoldingTransaction() {
    InputObjectState uncommittedState = null;
    _originalProcessUid = new Uid(Uid.nullUid());
    try {
        uncommittedState = _participantStore.read_uncommitted(_ourUid, _type);
    } catch (ObjectStoreException e) {
        txojLogger.i18NLogger.warn_recovery_RecoveredTransactionalObject_6(e);
        // probably
        return false;
    }
    /*
         * Get the transaction and original process information from the saved
         * state.
         */
    _originalProcessUid = null;
    _owningTransactionUid = null;
    try {
        Header hdr = new Header();
        unpackHeader(uncommittedState, hdr);
        _originalProcessUid = hdr.getProcessId();
        _owningTransactionUid = hdr.getTxId();
        if (txojLogger.logger.isDebugEnabled()) {
            txojLogger.logger.debug("RecoveredTransactionalObject::findHoldingTransaction - uid is " + _owningTransactionUid);
        }
        return _owningTransactionUid.notEquals(Uid.nullUid());
    } catch (Exception e) {
        txojLogger.i18NLogger.warn_recovery_RecoveredTransactionalObject_8(e);
    }
    return false;
}
Also used : InputObjectState(com.arjuna.ats.arjuna.state.InputObjectState) Uid(com.arjuna.ats.arjuna.common.Uid) ObjectStoreException(com.arjuna.ats.arjuna.exceptions.ObjectStoreException) Header(com.arjuna.ats.internal.arjuna.Header) ObjectStoreException(com.arjuna.ats.arjuna.exceptions.ObjectStoreException)

Example 4 with Header

use of com.arjuna.ats.internal.arjuna.Header in project narayana by jbosstm.

the class SubordinateAtomicAction method restore_state.

public boolean restore_state(InputObjectState os, int t) {
    _theXid = null;
    try {
        unpackHeader(os, new Header());
        boolean haveXid = os.unpackBoolean();
        if (haveXid) {
            _theXid = new XidImple();
            ((XidImple) _theXid).unpackFrom(os);
            _parentNodeName = os.unpackString();
        }
    } catch (IOException ex) {
        return false;
    }
    return super.restore_state(os, t);
}
Also used : XidImple(com.arjuna.ats.jta.xa.XidImple) Header(com.arjuna.ats.internal.arjuna.Header) IOException(java.io.IOException)

Example 5 with Header

use of com.arjuna.ats.internal.arjuna.Header in project narayana by jbosstm.

the class SubordinateAtomicAction method save_state.

public boolean save_state(OutputObjectState os, int t) {
    try {
        // pack the header first for the benefit of the tooling
        packHeader(os, new Header(get_uid(), Utility.getProcessUid()));
        if (_theXid != null) {
            os.packBoolean(true);
            ((XidImple) _theXid).packInto(os);
            os.packString(_parentNodeName);
        } else
            os.packBoolean(false);
    } catch (IOException ex) {
        return false;
    }
    return super.save_state(os, t);
}
Also used : XidImple(com.arjuna.ats.jta.xa.XidImple) Header(com.arjuna.ats.internal.arjuna.Header) IOException(java.io.IOException)

Aggregations

Header (com.arjuna.ats.internal.arjuna.Header)5 IOException (java.io.IOException)4 XidImple (com.arjuna.ats.jta.xa.XidImple)2 Uid (com.arjuna.ats.arjuna.common.Uid)1 ObjectStoreException (com.arjuna.ats.arjuna.exceptions.ObjectStoreException)1 InputObjectState (com.arjuna.ats.arjuna.state.InputObjectState)1