← Lab

Two-Phase Commit

Step through the protocol, trigger failures, and see why 2PC can block.

Click a participant to toggle its vote. Click any node to kill/revive it.
Phase: IDLE · Decision: · Alive: 4/4
Press Begin Transaction to start.

How Two-Phase Commit Works

Two-Phase Commit (2PC) solves the atomic commit problem: when a transaction spans multiple nodes, either all of them commit or all of them abort. No partial results.

A designated coordinator drives the protocol in two phases:

Phase 1 — Prepare. The coordinator sends a PREPARE message to every participant. Each participant decides whether it can commit — checking constraints, acquiring locks, writing a prepare record to its log. If it can, it votes YES. If not, it votes NO. Once a participant votes YES, it's "in doubt" — it has promised to commit if told to, but can't decide on its own.

Phase 2 — Commit/Abort. If every participant voted YES, the coordinator decides COMMIT and tells everyone. If any participant voted NO (or didn't respond in time), the coordinator decides ABORT. Participants apply the decision and release their locks.

This works because no participant ever commits unless the coordinator explicitly says so. The coordinator only says COMMIT if it got unanimous YES votes.

The blocking problem. If the coordinator crashes after sending PREPARE but before broadcasting its decision, participants that voted YES are stuck. They're holding locks, they've promised to commit, but they don't know the outcome. They can't commit (maybe the coordinator decided to abort). They can't abort (maybe the coordinator decided to commit). They just... wait. This is 2PC's well-known weakness — it's a blocking protocol.

Try it above: kill the coordinator right after it sends PREPARE. Watch the participants sit in PREPARED state with no way forward. This is exactly the scenario that motivated Three-Phase Commit (3PC) and eventually Paxos Commit, which avoid blocking by adding an extra round of communication or using consensus to agree on the outcome.

Despite this limitation, 2PC is everywhere in practice — distributed databases, XA transactions, and any system that needs atomic cross-shard writes. The blocking problem is usually handled operationally: coordinators write their decisions to durable logs before crashing, and recovery procedures exist to replay the decision. But the fundamental vulnerability is real, and understanding it is key to understanding why distributed transactions are hard.