2PC vs Saga vs TCC — Distributed Transactions
One transaction, many services
A single business action — “place an order” — may touch Order, Payment, and Inventory services, each with its own
database. There’s no single COMMIT across them. Three patterns reconcile this, trading consistency,
locking, and complexity differently.
Two-Phase Commit (2PC) — strong, but blocking
A coordinator runs two phases: Prepare (every participant locks resources and votes “ready”), then Commit (if all voted yes, everyone commits; otherwise everyone aborts). It gives ACID across services — but it’s synchronous and blocking: if the coordinator crashes after Prepare, participants sit holding locks, unable to proceed. That fragility is why 2PC is avoided in high-scale systems.

Saga — local transactions + compensation
A Saga replaces the distributed lock with a sequence of local transactions, each with a compensating transaction that semantically undoes it. If step 3 fails, you run the compensations for steps 2 and 1 (refund, release stock). Two flavours: choreography (services react to each other’s events) and orchestration (a central coordinator drives the steps). No locks, no blocking — but only eventual consistency and no isolation, so you must design idempotent steps and handle intermediate states.

TCC (Try-Confirm-Cancel) — explicit reservations
TCC splits each step into Try (reserve resources — e.g. hold the stock, authorize but don’t capture payment), then Confirm (commit the reservation) or Cancel (release it). It gives more control than a Saga and avoids 2PC’s locks, at the cost of building three operations per service.
Choosing
| 2PC | Saga | TCC | |
|---|---|---|---|
| Consistency | Strong (ACID) | Eventual | Eventual, reservation-based |
| Locking | Holds locks across the txn | None (compensations) | Soft reservation |
| Failure mode | Coordinator crash blocks participants | Compensations may be complex | More code, explicit cancel paths |
| Best for | Few services, short txns, strict ACID | Microservices, long-running flows | When you need isolation-ish reservations |
Takeaways
- 2PC: strong consistency, but synchronous and blocking — doesn’t scale across many services.
- Saga: the microservices default — local txns + compensations, eventual consistency, needs idempotency.
- TCC: Saga with explicit reserve/confirm/cancel when you need tighter control.
- Reliably emitting the events that drive a Saga is the job of the Transactional Outbox pattern.
- Production smells: 2PC spanned across plain HTTP services with no real XA support hangs under partial failure; a saga with no reconciliation job leaves money stuck in intermediate states forever. Choose the model that matches your failure budget, not the blog trend.
L0 · 2PC buys atomicity by holding every participant's locks open until one coordinator's vote decides commit-or-abort for all; Saga and TCC each buy back availability by trading that lock for local commits plus compensating or reserved-undo logic.
L1 · ① Concurrency — "under concurrent load, why does 2PC's throughput collapse while Saga's doesn't?"
Trap: "2PC gives atomicity, done — that's the whole point of running a two-phase protocol."
Bar: Each participant acquires and holds its prepare-phase locks (the rows/tables the txn touches) from Prepare until the coordinator's Commit arrives — at least two network round-trips — so every other transaction touching those same rows queues behind the slowest participant in the cohort. Saga instead commits and releases each local lock within a single hop per step, so lock hold time tracks one service's local commit, not the whole cohort's round-trip. row-lock hold time & deadlocks
L2 · ② Failure — "the coordinator crashes after telling node A to commit but before reaching node B — what happens to B?"
Trap: "It'll just retry once the coordinator restarts — no real problem."
Bar: The coordinator durably logs its decision before phase 2 begins, so on recovery it can replay the same verdict to stragglers — but B, having already voted yes with no way to safely decide alone, sits "in-doubt" holding its locks until that recovery happens. That indefinite hold is provably unavoidable in plain 2PC without an extra communication round, which is exactly what consensus-backed commit protocols add. why consensus is hard (FLP, Paxos vs Raft)
L3 · ⑤ Adversary/Edge — "a reader queries inventory between Saga step 2 (stock decremented) and step 3 failing and compensating — what do they see, and why does it matter?"
Trap: "Saga is just a slower transaction — isolation still holds until the whole thing finishes."
Bar: The reader sees the decremented stock as committed fact, because it is, locally — the saga hasn't finished and will later compensate it away, but nothing stopped that reader from acting on the interim state. Real sagas guard this with a semantic lock (a pending/reserved status flag on the row) so concurrent readers treat mid-saga state as provisional rather than trusting a bare compensating write to undo it cleanly. saga in depth: orchestration, choreography, pivot transaction
L4 · ⑥ Cost/Simplicity — "why not just use TCC everywhere — it fixes Saga's isolation gap, doesn't it?"
Trap: "TCC = Saga with real isolation, for free."
Bar: TCC requires every participant to expose three idempotent, retry-safe operations (Try reserves, Confirm commits, Cancel releases) plus a reservation-expiry timeout, so an orchestrator crash between Try and Confirm doesn't leak the hold forever — that's triple the endpoints and a TTL-management concern per service. That cost is why teams reserve TCC for a handful of high-value flows (payment holds, seat locks) instead of the whole checkout path. idempotency & dedup mechanics
L5 · ③ Scale — "checkout now fans out to 200 services — does any of these three protocols still work?"
Trap: "Saga scales fine, it has no locks."
Bar: 2PC's blocking window is set by the slowest of 200 participants, so tail latency and lock contention both multiply with fan-out, while a single Saga orchestrator issuing 200 sequential steps becomes a throughput bottleneck and coordination single point of failure even with zero database locks. At real scale teams split the saga at its pivot transaction into independently-retryable sub-sagas and drive steps off a durable outbox-backed event bus instead of one orchestrator's call graph. transactional outbox: solving the dual-write problem
The floor keeps dropping: the coordinator's own decision log is a single point of failure too — replicate it for durability and you've built a mini-consensus system just to make 2PC safe. At that point the real staff question isn't "which protocol" but "why does any business step need a lock spanning two services at all" — redraw ownership so each aggregate has a single writer and Saga/outbox is the default, and 2PC's entire failure mode becomes moot rather than mitigated.
Self-locate: died at L1 → mid-level; L4+ → staff signal.
Facing any new concept? Hit it with the six: concurrent? failing? at 100×? over time? adversarial? worth the cost? — that's the interviewer's whole playbook.
Re-authored for this guide. Concepts are standard public-domain distributed-systems theory (Gray for 2PC; Skeen for the blocking/non-blocking commit result; Lamport and Ongaro–Ousterhout for consensus; Garcia-Molina & Salem for sagas). Diagrams adapted from Karan Pratap Singh’s System Design (MIT) and concepts from Designing Data-Intensive Applications.
🤖 Don't fully get this? Learn it with Claude
Stuck on 2PC vs Saga vs TCC — Distributed Transactions? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **2PC vs Saga vs TCC — Distributed Transactions** (System Design) and want to truly understand it. Explain 2PC vs Saga vs TCC — Distributed Transactions from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **2PC vs Saga vs TCC — Distributed Transactions** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **2PC vs Saga vs TCC — Distributed Transactions** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **2PC vs Saga vs TCC — Distributed Transactions** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.