AlpineTransMgr:
DEFINITIONS =
BEGIN
Call worker -> coordinator.
Duplicate call from worker to coordinator (caused e.g. by worker crash or major
communications failure) is an error.
RegisterWorker:
PROC [
conversation: AlpineEnvironment.Conversation,
trans: AlpineEnvironment.TransID]
RETURNS [RegisterWorkerResult];
! (none);
RegisterWorkerResult: TYPE = {ok, transNotActive, duplicateCall};
Calls coordinator -> worker.
Duplicate calls are ok, so implementations of these procedures must be
prepared for them.
WorkerPrepare:
PROC [
conversation: AlpineEnvironment.Conversation,
trans: AlpineEnvironment.TransID,
newTrans: AlpineEnvironment.TransID]
RETURNS [WorkerState --{notReady, readOnlyReady, ready}--];
! Refused {wrongCoordinator};
if trans.state = active, then (attempt to make trans ready):
if trans has performed only reads, return "readOnlyReady"
else if trans can't get ready, return "notReady"
else (trans gets ready) return "ready"
else if trans.state = ready, return "ready"
else (trans has no volatile state or trans.state = completing) return "notReady"
if "notReady" or "readOnlyReady" result, worker erases volatile
state of transaction, and coordinator need not call WorkerFinish.
if "ready" result, coordinator must call WorkerFinish to complete transaction.
if newTrans # nullTransID and "readOnlyReady", worker starts newTrans
and transfers downgraded locks from trans to newTrans.
if newTrans # nullTransID and "ready", worker starts newTrans and if
WorkerFinish[requiredOutcome: commit] follows, worker transfers downgraded
locks from trans to newTrans.
WorkerFinish:
PROC [
conversation: AlpineEnvironment.Conversation,
trans: AlpineEnvironment.TransID,
requiredOutcome: RequiredOutcome --{abort, commit}--];
! Refused {wrongCoordinator, notReady};
if trans.state = active and requiredOutcome = commit then ERROR Refused[notReady]
else if trans.state = active or ready, then make trans go to requiredOutcome
else (trans has no volatile state, or trans.state = completing) return.
RequiredOutcome: TYPE = AlpineEnvironment.CommitOrAbort;
WorkerState: TYPE = AlpineEnvironment.WorkerState;
Refused: ERROR [why: Refusal];
Refusal: TYPE = {wrongCoordinator, notReady};
END.