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;
}
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;
}
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;
}
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);
}
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);
}
Aggregations