The Consensus Problem and Atomic Commit (2PC)
Hook #
The last course ended on a hard truth: consensus — getting a set of nodes to agree on a single value — is impossible to guarantee in an asynchronous system with failures (FLP). This course is how we do it anyway, in practice, and it's the machinery behind every replicated database, every leader election, every distributed lock you've ever relied on. But before the elegant solutions (Raft, next lesson), you need to see the intuitive one and understand why it's not enough. Two-Phase Commit (2PC) is the natural first answer to "how do multiple nodes agree to commit a transaction together (all or nothing)?" — a coordinator asks everyone "can you commit?", and if all say yes, tells everyone "commit." It's simple, it's widely used, and it has a fatal flaw that motivates everything after it: if the coordinator crashes at the wrong moment, the other nodes are stuck forever, unable to safely commit or abort. This lesson is the consensus problem and its first, flawed solution — the setup for why we need real consensus algorithms.
What you'll be able to do by the end of this lesson #
- State the consensus problem precisely: multiple nodes must agree on a single value, such that they all decide the same value (agreement), it's a value someone proposed (validity), and they eventually decide (termination).
- Explain the Two-Phase Commit protocol (prepare/vote phase, then commit/abort phase) and the coordinator's role.
- Explain 2PC's fatal weakness — it blocks if the coordinator fails after the prepare phase — and why that makes it unsuitable as a general fault-tolerant consensus mechanism.
- Understand why atomic commit across distributed nodes is a form of consensus, connecting it back to the transactions you learned at the single-database level.
A quick try before we start #
Before reading: you need two separate databases to either both commit a change or both abort — never one without the other (say, deducting from an account in one system and crediting in another). A coordinator asks both "ready to commit?"; both say "yes, prepared"; the coordinator sends "commit!" to the first... and then crashes before telling the second. The first has committed; the second is sitting in "prepared," waiting. What can the second node safely do now? (Nothing safe — it can't abort, because the first already committed; it can't commit on its own authority, because it doesn't know the coordinator's decision. It's stuck.) That deadlock-on-coordinator-failure is 2PC's fatal flaw, and feeling it is the point of the whole lesson.
Why this matters here #
Consensus is the single most important primitive in distributed systems, and 2PC in particular is something you've almost certainly relied on — distributed transactions (XA transactions), some microservice sagas, and cross-system atomic operations use it or its descendants. Understanding 2PC's blocking problem is directly practical: it's why the industry has largely moved away from distributed transactions toward other patterns (sagas with compensation, event-driven eventual consistency, or a single consensus system as the source of truth), and why "just use a distributed transaction" is often the wrong answer at scale. More broadly, this lesson teaches you to recognize consensus problems in disguise — leader election, distributed locks, "which node owns this shard?", "did this operation happen?" are all consensus — and once you can name the problem, you can reach for the right tool (a real consensus system) instead of building a fragile 2PC-style coordinator yourself. The single most common distributed-systems mistake is hand-rolling coordination that a battle-tested consensus system should handle.
Within the course, this is the problem statement that the rest of the course solves. 9.1 established the constraints (failures, no shared clock, FLP); this lesson names the central challenge (consensus / atomic agreement) and shows the intuitive-but-broken solution. Lesson 2 (Raft) is the good solution — consensus that survives node and coordinator failures by not depending on a single coordinator. Everything else in the course (replication, quorums, consistency models) either builds on consensus or is an alternative that avoids needing it. And it spirals back to the databases course: a single-node transaction's atomicity (all-or-nothing) was easy because one machine decides; distributed atomic commit is hard precisely because now multiple machines must agree despite failures — the transaction concept you know, lifted into the distributed world where it becomes a consensus problem.
The engineer's lens #
The core insight is that an enormous range of distributed problems are secretly the same problem — consensus — and recognizing that lets you reach for one well-understood, battle-tested solution instead of hand-rolling a fragile coordinator for each. Leader election ("which node is in charge?") is consensus on the identity of the leader. A distributed lock ("who holds this lock?") is consensus on ownership. Atomic commit ("did we all commit?") is consensus on the outcome. Cluster membership ("who's in the group?"), shard assignment ("who owns this partition?"), configuration agreement — all consensus. This unification is powerful because consensus is hard (FLP-hard) and getting it subtly wrong causes catastrophic bugs (split-brain, where two nodes both think they're the leader and corrupt data). So the practical wisdom is: when you find yourself needing distributed agreement, do not build it yourself — recognize it as consensus and delegate to a system built for it (etcd, ZooKeeper, Consul, or a database that provides it), all of which implement Raft or Paxos correctly. The number of production disasters caused by hand-rolled leader election and DIY distributed locks is enormous, and every one of them is an engineer who didn't recognize they were solving consensus. Naming the problem is half the battle; the other half is not reinventing its solution.
The second lens is the blocking problem of 2PC as a lesson in single points of failure — the coordinator is a SPOF, and eliminating SPOFs is the recurring move that separates fragile designs from resilient ones. 2PC works beautifully until the coordinator fails at the wrong moment, at which point the entire system is stuck: the participants have promised to commit but can't proceed without the coordinator's decision, and there's no safe way for them to decide on their own. The coordinator is a single point of failure, and its failure doesn't just slow things down — it blocks, indefinitely, holding locks and freezing progress. This is the exact anti-pattern you're trained to spot in any architecture: a single component whose failure takes down the whole system. The fix, here and everywhere, is to distribute the decision-making so no single node's failure blocks progress — which is precisely what Raft does (a majority can make progress even if any single node, including the leader, fails, because leadership can move). 3PC tries to patch 2PC's blocking with an extra phase but doesn't fully solve it (it breaks under network partitions). Recognizing "this design has a coordinator/master/leader that everything depends on — what happens when it dies?" is a core resilience instinct, and 2PC is the canonical cautionary tale: a protocol that's correct when everything works and catastrophic when the one special node fails.
What to focus on in DDIA Chapter 9 (2PC section) #
- The two phases and the coordinator's role. Phase 1: coordinator asks all participants to prepare (vote yes/no); a "yes" is a binding promise to be able to commit. Phase 2: if all voted yes, coordinator says commit, else abort. Understand that after voting yes, a participant has given up its right to abort unilaterally — that's what makes it stuck if the coordinator vanishes.
- The blocking problem — the load-bearing takeaway. Focus on exactly when 2PC blocks (coordinator fails after some participants have prepared but before all learn the decision) and why the participants can't safely resolve it themselves. This is the flaw that motivates real consensus.
- Why this connects to single-node transactions. Atomic commit is the distributed version of the atomicity you learned in the databases course. See it as "the same all-or-nothing guarantee, now across machines that can fail independently."
- Skip on first pass: the detailed 3PC protocol (know it exists and imperfectly addresses blocking), XA transaction API specifics, and the formal consensus-property proofs. Get the consensus problem, 2PC's mechanics, and its blocking flaw.
Explain it back #
Explain to a colleague why Two-Phase Commit can leave a system stuck forever if the coordinator crashes at the wrong time, and what that teaches about distributed system design. A strong answer: after participants vote "yes, prepared" in phase 1, they've committed to being able to commit and given up the right to abort on their own — so if the coordinator crashes before delivering the phase-2 decision, a prepared participant can neither commit (it doesn't know the decision was "commit") nor abort (another participant may have already committed), and it blocks indefinitely holding locks. The coordinator is a single point of failure whose crash freezes the whole system — which is why resilient designs distribute decision-making (as Raft does) so no single node's failure blocks progress. Bonus: name a real consensus-in-disguise problem (leader election, distributed lock) and say why you'd use a battle-tested system rather than hand-roll it.
Where this connects #
Backward: 9.1's FLP impossibility (consensus can't be guaranteed under pure asynchrony — 2PC's blocking is a concrete face of that difficulty) and the databases course's transactions (atomic commit is distributed atomicity — the all-or-nothing guarantee lifted across fallible machines). The single-point-of-failure lesson echoes the redundancy themes from RAID and failure models.
Forward: Lesson 2 is the real solution — Raft — which achieves fault-tolerant consensus by removing the single-coordinator dependency (a majority makes progress even if the leader dies). Everything in the course builds on consensus: state machine replication (lesson 3) uses it to keep replicas in agreement, and the consistency models (lesson 4) describe what guarantees consensus-backed systems can offer.
That's the free preview. Sign in to continue this course.
Sign in to continueNew here? Make a desk →