A transaction crossing partitions needs one outcome for work held by several owners. If it commits, every owner must honour the purchase. If it aborts, none may keep its part. Distributed atomic commit is the protocol that makes that outcome recoverable, including when the process coordinating it disappears.
Replicas solve a different part of the problem. Three copies of the order shard can agree to store an order while three copies of the stock shard agree to leave stock alone. Both groups have agreed internally, but the purchase is incomplete. The transaction needs agreement about whether those groups’ work belongs to a committed purchase.
The example uses the shop placement from Sharding and distributed SQL. Customer shard A holds Mina’s order work; product shard P holds shared stock. We first use a simple two-phase commit model, then give its decision state surviving replicas. These are illustrative protocol schedules, not observations from a running database or a description of every distributed SQL engine.
One purchase, two owners
Return to just before purchase 103. The order and its lines do not yet exist. P7 has one blue mug and P3 has twelve packs of tea. Mina wants the mug at 20.00 and two packs at 4.50 each: a total of 29.00. A successful purchase creates pending order 103 with those two lines and reduces stock to P7 = 0 and P3 = 10. It records no payment.
Committing A first can retain the order and lines, then lose contact with P before stock changes. Committing P first can consume the stock, then lose contact with A before an order exists. Replicas within A or P can faithfully preserve either incomplete result.
Figure 1 The gap between two local commits
A · customer shard
Create pending order 103
Line 1: P7 × 1 at 20.00
Line 2: P3 × 2 at 4.50
A₁ · A₂ · A₃ copy this work
P · product shard
Guard both stock decrements
P7: 1 → 0
P3: 12 → 10
P₁ · P₂ · P₃ copy this work
A commits → contact with P lost
Order and lines retained. Stock unchanged.
P commits → contact with A lost
Stock reduced. No order or lines.
The purchase needs: both commit or both abort.
Two independent failure examples, each stopped between separate local commits. Replicas can preserve either incomplete result. A and P name data owners, each of which can itself have several replicas.
Changing the order of the calls changes which incomplete result is possible. Retrying the second call may eventually finish it, but that leaves the application responsible for recovering a purchase that has already partly committed. It has not provided the database transaction’s all-or-nothing outcome.
Instead, A and P join one transaction as participants. A coordinator gathers their readiness and records the transaction’s decision. These are roles: the coordinator might run on a participant’s machine, and the participants are not necessarily separate SQL connections controlled by the application.
Preparing to commit
A participant cannot promise to commit merely because its work looks valid now. P must still be able to supply the mug when the decision arrives. It must also survive a restart without forgetting what it promised.
In two-phase commit, the first phase asks participants to prepare. A participant checks whether it can finish its work, stores enough state durably to finish after a failure, and retains the protection needed to honour that promise. In a locking implementation, that includes keeping the relevant locks. Only then does it answer “prepared”.
Prepared means ready to obey a later commit or abort decision. It does not mean committed. Mina has no successful purchase yet, and other transactions must not treat its provisional order or stock changes as ordinary committed facts.
The coordinator needs a positive prepared reply from every participant before choosing commit. A refusal from the stock owner instead prevents the purchase.
Two promises, one outcome
Figure 2. Classic two-phase commit, drawn as an illustrative purchase rather than a measured engine trace.Figure as text
The coordinator asks Orders and Stock to prepare. Prepared work and protection are retained durably. Only after both positive votes can a durable COMMIT be chosen and delivered. A refusal instead requires ABORT and discarding the provisional work. Prepared alone is not committed.
P might find insufficient stock, fail a required check, or be unable to store its prepared state. Any of these refusals prevents commit. This failure does not require a second buyer or a change to the shop’s starting rows.
A participant that has not promised can abandon its work. Once it has answered “prepared”, it cannot take a timeout as permission to abort on its own. The coordinator may already have committed and told the other participant. Giving the mug away at that point would make A’s committed order impossible to honour.
Recording one decision
The second phase chooses and delivers the outcome. The coordinator can record COMMIT only after A and P have both prepared. If either refuses, it records ABORT. If a required reply does not arrive, it may choose abort while no final decision has been made; a missing reply never counts as a positive vote.
The durable decision comes before its notifications. Suppose the coordinator instead told A to commit, then crashed before recording that choice. Recovery could find no decision and tell P to abort. Recording first gives recovery the fact it needs to finish the same choice.
A may learn COMMIT before P. That is allowed: an undecided participant can still be waiting while another has finished. What is forbidden is an opposing outcome. After COMMIT is durably chosen, P must eventually honour it when it can recover and communicate; it cannot substitute ABORT because delivery was slow.
The model gives each transaction a fixed participant list, durable prepared records and a durable final decision. It assumes processes can stop and recover, messages can be delayed, lost or repeated, and storage preserves acknowledged durable state. Decision messages refer to the same transaction; repeated delivery completes that transaction rather than decrementing stock again. Record retention and recovery must preserve enough identity and outcome history to maintain that rule. These are protocol assumptions, not an application retry recipe.
When the coordinator disappears
Stopping a coordinator does not erase a durable decision. It can make the evidence inaccessible. Recovery must distinguish those two facts before it tells any participant what to do.
Prepared, with no known outcome
Take classic two-phase commit with one coordinator’s durable log. Both participants have prepared; the coordinator disappears and neither participant has learnt a final outcome. A and P can still talk. They can confirm each other’s readiness, but readiness is not evidence of what the coordinator decided.
The coordinator could have recorded COMMIT after hearing both replies. It could instead have recorded ABORT after its deadline expired while a reply was still in transit. Neither history is ruled out by “we both prepared”. If no accessible process or durable record can establish the outcome, the prepared participants wait. This is the blocking case of classic two-phase commit.
Making the decision state recoverable without the original coordinator changes this failure case. It requires more than starting a replacement process: the replacement needs authoritative evidence of the decision.
A lost process does not choose a new outcome
Figure 3. The recovery branches are independent failures. Recovery must establish authority, not trust an arbitrary copy.Figure as text
Without an accessible coordinator decision, two prepared participants keep their promises. In the replicated case COMMIT was established on D1 and D2: after D1 fails, D2 and D3 recover authority and finish Stock’s prepared work. If only the older D3 remains reachable, absence of COMMIT there does not authorise abort.
A decision that outlives its coordinator
In the replicated version of the model, three voters D1, D2 and D3 keep the transaction decision state. A final decision is established through their agreement protocol. The coordinating process can then disappear while the state it used survives. This is the same distinction between a process and authoritative history developed in Sharding and distributed SQL.
Suppose COMMIT was established with durable copies on D1 and D2. D1 then fails. D2 and D3 can recover authority through the protocol, which preserves the agreed history, and a recovery process learns COMMIT. It delivers that existing decision to P. It does not take a new vote on whether Mina should get the mug.
In a separate failure, neither participant has learnt COMMIT and only D3 is reachable from the decision group. Its older copy contains no final decision. Reading that copy is not proof that COMMIT never happened. With no accessible witness to the decision and no quorum to recover authority, the participants must wait. Replicating the decision improves the failures it can survive; it does not make every network split available.
If recovery authoritatively establishes that no final decision was made, it can continue under the protocol’s rules, including choosing abort. That requires both recovering the relevant state and preventing an old coordinator from establishing a conflicting outcome. Merely appointing a replacement process supplies neither guarantee.
A replicated decision record is one way to explain recoverable coordination. It is not the only commit design. Consensus can also be integrated more directly into commit, as in Paxos Commit. The questions remain which evidence makes the outcome final, who can recover it, and which missing participants or quorums can stop progress.
Commit, visibility and cleanup
The decision and the work of finishing it happen at different moments. A participant may still hold a provisional record after COMMIT has been chosen. A later operation encountering that record must respect its transaction’s outcome: it may wait, obtain the decision or help finish the work, according to the engine. It cannot simply ignore unresolved stock and sell the mug again.
Nor does atomic commit require every physical copy to change at the same instant. A system can establish commitment before it has installed every final row form or removed every provisional marker. The engine’s read and isolation machinery must make that delay safe for the reads it permits. CockroachDB, for example, separates commitment from asynchronous resolution of provisional writes; its native protocol is developed in CockroachDB transactions and retries.
Atomic commit also does not give two separate reads a common snapshot. A report can read A before the purchase, see no order, then read P after it and see stock 0. Both answers can be correct when obtained; together they do not describe one committed shop state. Time, snapshots and distributed reads establishes how related reads choose a safe common history.
Isolation remains necessary for competing purchases. Two transactions can each commit all their own writes and still violate a rule if their reads and decisions were allowed to race incorrectly. Here P must enforce the stock guard at the shared authority, and the complete purchase must use suitable isolation. Transactions and isolation develops that reasoning.
What the transaction must coordinate
A and P are the two data participants identified so far. That does not promise this purchase always contacts only two groups. Constraints and indexes also have locations, and the transaction must include the work required to keep their rules true.
For example, the shop’s order number identifies an order globally. If A and B can independently accept 103, their local checks have not enforced that rule. An implementation using a separate globally enforced order-key index must coordinate its claim with the order and stock work. A foreign-key check may likewise need to protect a remotely owned customer, order or product reference against a conflicting change.
Figure 4 Count the rule’s work
One transaction boundary
A Order + lines↔P Guarded stock
↕ if separately ownedGlobal order-key claim · index updates · reference protection
Every required participant must be covered by the outcome.
An ownership audit, not an asserted engine layout. The lower box shows possible additional work; an engine can place some of it with A or P, use other enforcement mechanisms, or restrict supported constraints.
Check the actual mechanism and its scope. Adding a customer routing column or keeping order and lines together does not prove global uniqueness or reference integrity. A read-only check can also need concurrency protection even when it creates no row. Engines can optimise participants that need no second-phase work, so count the protocol’s required work rather than counting tables.
The protocol also determines the waits. Prepare messages must reach the required owners; those owners must finish checks and retain their promises durably; their replies must reach the coordinator before it can choose commit. The decision must then become durable and reach whoever needs it. Replicated participant state and replicated decision state add their own agreement waits.
Some of those waits overlap. Others depend on an earlier answer. Co-locating coordinator and participant can remove network messages, and an engine can combine writes, pipeline work or use a faster commit path. “Two phases” is therefore not one fixed number of network round trips or a measure of elapsed time. Trace the actual dependent messages and durability waits to assess latency.
Co-location reduces coordination when it brings the complete rule’s work together. Keeping Mina’s order and its lines on A helps, but stock on P remains authoritative for every buyer. A copied catalogue value does not provide a second allowance to sell P7. During a recovery wait, prepared work can also retain locks or other protected state, holding up transactions that need the same resources. A slow decision can therefore affect more than its original caller.
Recovering the purchase at the application boundary
Now let the database finish the distributed purchase and lose its reply to the application. The participants can all agree on COMMIT while the application still does not know whether it succeeded. Restarting a coordinator, finishing P’s work and recovering Mina’s request are separate jobs.
The caller retains the existing request identity, purchase-103, scoped to customer 1’s purchase operation, with the same canonical basket. Its durable terminal result belongs in the same transaction as the successful purchase. Re-entering the protected request protocol recovers accepted order 103 without buying again. An unresolved database transaction may still make that recovery wait; a caller’s timeout does not turn it into an abort.
Retries and uncertain commit outcomes develops the complete request protocol, including competing attempts, payload mismatches and retained results. CockroachDB transactions and retries maps the reasoning to native transaction state and error handling. Understand its optimised commit paths through their own contract rather than assuming the classic two-phase message sequence.
External delivery has another boundary. Recording this purchase does not charge a card or send an email, and rolling it back cannot reverse an outside service. Outboxes and database-backed jobs shows how to commit a durable intention with the purchase and recover the later delivery.
Sources and further reading
Checked on 25 October 2026. The purchase, message schedules and replicated decision group are illustrative models. No cluster timings, fault injections or native transaction traces are reported.
Jim Gray and Leslie Lamport, Consensus on Transaction Commit, especially sections 2–3 and 6: atomic commit requirements, durable state, classic two-phase commit’s blocking case, and recovery. Sections 4–5 develop Paxos Commit.
Microsoft’s protocol documentation, Two-Phase Commit Protocol: readiness votes, the common outcome and the boundary on unilateral abort.
PostgreSQL 18, PREPARE TRANSACTION: a concrete prepared state that survives the session and keeps locks. This interface is intended for transaction managers, not ordinary application transaction code.
Google Cloud, Life of Spanner Reads & Writes: replicated splits, cross-split commit, application of mutations and the waits on the path. Secondary indexes and Foreign keys give concrete examples of index and integrity work beyond base-row writes.
CockroachDB, Transaction Layer: an example of an optimised atomic commit protocol and cleanup of provisional writes after commitment.