DIRECTORY OldAlpineEnvironment; OldAlpineTransMgr: DEFINITIONS = BEGIN RegisterWorker: PROC [ conversation: OldAlpineEnvironment.Conversation, trans: OldAlpineEnvironment.TransID] RETURNS [RegisterWorkerResult]; RegisterWorkerResult: TYPE = {ok, transNotActive, duplicateCall}; WorkerPrepare: PROC [ conversation: OldAlpineEnvironment.Conversation, trans: OldAlpineEnvironment.TransID, newTrans: OldAlpineEnvironment.TransID] RETURNS [WorkerState --{notReady, readOnlyReady, ready}--]; WorkerFinish: PROC [ conversation: OldAlpineEnvironment.Conversation, trans: OldAlpineEnvironment.TransID, requiredOutcome: RequiredOutcome --{abort, commit}--]; RequiredOutcome: TYPE = OldAlpineEnvironment.CommitOrAbort; WorkerState: TYPE = OldAlpineEnvironment.WorkerState; Refused: ERROR [why: Refusal]; Refusal: TYPE = {wrongCoordinator, notReady}; END. ΨOldAlpineTransMgr.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Calls between coordinator and worker in two-phase commit protocol. Last edited by Taft on 30-Jan-82 18:00:29 MBrown on October 22, 1982 8:52 pm Hauser, March 7, 1985 2:24:09 pm PST Call worker -> coordinator. Duplicate call from worker to coordinator (caused e.g. by worker crash or major communications failure) is an error. ! (none); Calls coordinator -> worker. Duplicate calls are ok, so implementations of these procedures must be prepared for them. ! 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. ! 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. Hauser, March 7, 1985 2:23:32 pm PST Nodified, added copyright. Κυ˜šœ™Icodešœ Οmœ1™<—JšœB™Bšœ™Jšœ™Jšœ"™"K™$—J˜šΟk ˜ J˜J˜—šœž œ˜ Jšž˜J˜Jšœ™JšœO™OJšœ$™$J˜šΟnœžœ˜J˜0J˜$šžœ˜Jšœ ™ ——Jšœžœ'˜AJ˜Jšœ™JšœF™FJšœ™J˜šŸ œžœ˜J˜0J˜$J˜'JšžœΟc$œ˜;Jšœ™Jšœ<™