com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::prepare for "+_theUid);
}
if (_theControl == null)
{
throw new INVALID_TRANSACTION(ExceptionCodes.SERVERAA_NO_CONTROL, CompletionStatus.COMPLETED_NO);
}
if (_theControl.isWrapper())
{
destroyResource(); // won't necessarily get another invocation!
return Vote.VoteReadOnly;
}
ServerTransaction theTransaction = (ServerTransaction) _theControl.getImplHandle();
// ThreadActionData.pushAction(theTransaction); // unnecessary if context goes with all calls.
int result = TwoPhaseOutcome.PREPARE_NOTOK;
/*
* Transaction may have locally timed out and been rolled back.
*/
int s = theTransaction.status();
if ((s == ActionStatus.RUNNING) || (s == ActionStatus.ABORT_ONLY))
result = theTransaction.doPrepare();
else
{
switch (s)
{
case ActionStatus.COMMITTING:
case ActionStatus.COMMITTED:
case ActionStatus.H_COMMIT:
result = TwoPhaseOutcome.PREPARE_OK;
break;
case ActionStatus.H_MIXED:
result = TwoPhaseOutcome.HEURISTIC_MIXED;
break;
case ActionStatus.H_HAZARD:
result = TwoPhaseOutcome.HEURISTIC_HAZARD;
break;
}
}
ThreadActionData.popAction();
if (jtsLogger.logger.isDebugEnabled())
{
jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::prepare for "+_theUid+" : "+TwoPhaseOutcome.stringForm(result));
}
/*
* If prepare failed, then rollback now.
*/
if (result == TwoPhaseOutcome.PREPARE_NOTOK)
{
try
{
rollback();
}
catch (HeuristicCommit ex1)
{
result = TwoPhaseOutcome.HEURISTIC_COMMIT;
}
catch (HeuristicMixed ex2)
{
result = TwoPhaseOutcome.HEURISTIC_MIXED;
}
catch (HeuristicHazard ex3)
{
result = TwoPhaseOutcome.HEURISTIC_HAZARD;
}
catch (SystemException ex4)
{
result = TwoPhaseOutcome.HEURISTIC_HAZARD;
}
}
switch (result)
{
case TwoPhaseOutcome.INVALID_TRANSACTION:
throw new INVALID_TRANSACTION(ExceptionCodes.INVALID_ACTION, CompletionStatus.COMPLETED_NO);
case TwoPhaseOutcome.PREPARE_OK:
return Vote.VoteCommit;
case TwoPhaseOutcome.PREPARE_NOTOK:
destroyResource(); // won't necessarily get another invocation!