We use analytics cookies.We use cookies to analyze site traffic and improve your experience.
Loading...
System Design Masterclass · Distributed Systems Core
Free preview: the first 2 parts of this 8-part lesson.
Already bought the course? Sign in to read the whole lesson.
this lesson is part of
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design courseread the rest of this lesson in
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design coursein Distributed Systems Core
This lesson is part of the full System Design Masterclass. Unlock it along with 769 other lessons for a one-time payment.
One-time payment by card or PayPal
Get Lifetime AccessOne-time payment: UPI, card or netbanking
Get Lifetime Access18 Foundation lessons are free, no payment needed. Try them now
It is easy and good
“It is really nice and good Please join the course”
The two-phase commit protocol has one devastating problem: if the coordinator crashes at the wrong moment, participants are stuck forever, unable to commit, unable to abort, holding locks in limbo. Dale Skeen proposed three-phase commit (3PC) in 1981 specifically to fix this blocking problem.
The insight is simple: 2PC jumps from "I promise I can commit" directly to "committed." There's no intermediate state. If the coordinator dies after the promise but before the commit, nobody knows what was decided.
3PC adds an intermediate "pre-commit" phase. Before telling participants to commit, the coordinator first tells them "I'm going to commit." This means any participant that has received the pre-commit message knows the decision, even if the coordinator dies afterward. The participant can safely commit on its own or tell other participants to commit.
In theory, 3PC is strictly better than 2PC, it's non-blocking under the assumption that no network partitions occur. In practice, 3PC is almost never used. The reason? The "no network partitions" assumption is completely unrealistic in any distributed system worth building. And 3PC fails catastrophically during partitions, one side might commit while the other aborts, violating atomicity.
This lesson is shorter than most because 3PC is more important as a concept (understanding why non-blocking is hard) than as a practical protocol.
Phase 1. CanCommit (same as 2PC's Prepare): Coordinator asks "Can you commit?" Participants respond YES or NO.
Phase 2. PreCommit (the new phase): If all said YES, coordinator sends "PRE-COMMIT", signaling "I intend to commit." Participants acknowledge but don't commit yet.
Phase 3. DoCommit: Coordinator sends "DO-COMMIT." Participants commit.
| Phase | 2PC | 3PC |
|---|---|---|
| 1 | Prepare (vote) | CanCommit (vote) |
| 2 | Commit/Abort | PreCommit/Abort |
| 3 | . | DoCommit |
Why this helps: If the coordinator crashes after Phase 2 (PreCommit), any participant that received the pre-commit knows the coordinator decided to commit. It can either commit on its own after a timeout or inform other participants. The transaction isn't stuck.
Why this breaks with partitions: Imagine the coordinator sends PreCommit to participants A and B, but the message to C is lost (network partition). The coordinator crashes. A and B got pre-commit and decide to commit after a timeout. C never got pre-commit and decides to abort after a timeout. Atomicity is violated. A and B committed, C aborted.
The lesson here: Non-blocking commit protocols are impossible in the presence of network partitions and process failures (this is related to the FLP impossibility result). You can have non-blocking commit in a synchronous system (bounded message delays), but real networks are asynchronous.