Everyone votes YES, then one forced record decides
Each participant forces a prepared record and votes. If all say YES, the coordinator forces a commit record: the commit point. Then everyone commits.
All three voted YES, then the coordinator crashed. Why not just commit, or abort?
The catch
Each is in doubt: for all it knows, a peer voted NO or COMMIT was decided. It waits, holding locks.
99.6%
available when four 99.9% participants must all vote
0.999⁴ ≈ 99.6%. Over a 30-day month, that’s about 173 minutes of failed orders instead of 43, before counting the coordinator.
Is 2PC just bad?
Bad: XA between services
Gateways can’t prepare, and every service’s outage becomes every order’s.
Good: Inside one database
Spanner writes 2PC records through Paxos, so a machine failure can’t lose the decision.
The restaurant says no. Undo the charge with a refund.
Each step commits locally; on failure, compensations run newest first. Undoing “charge ₹450” means “refund ₹450”, a new ledger entry, not a deleted charge.
Arrange the steps around the point of no return
- Compensatable first: create the order PENDING, charge ₹450
- Pivot: the restaurant accepts. You can’t uncook a biryani
- Retriable after: assign a rider, confirm, notify
No locks: someone can spend money that gets undone
B pays ₹550 using A’s unbacked ₹500 top-up. A’s bank debit fails; the wallet ends at −₹450. Hold credits as PENDING until the saga ends.
Remember
Keep 2PC inside one database. Across services, run a saga: local commits, refunds as compensations, PENDING states for isolation.