Distributed commit is the problem of making sure an operation is performed by every node in a distributed system or none at all.

One-Phase Commit

The simplest solution is to elect one node as the coordinator, which tells all other nodes (subordinates) whether to commit or abort a transaction. However, this leaves us with two problems:

  1. A subordinate canโ€™t independently abort the transaction if thereโ€™s a problem.
  2. The coordinator might crash, leaving the system in an undefined state.

Two-Phase Commit (2PC)

To address these issues, weโ€™ll use two rounds of communication.

  1. Voting: first, the coordinator sends a โ€œprepareโ€ message to each subordinate, and they respond with โ€œyesโ€ or โ€œnoโ€ depending on whether theyโ€™re able to commit. During this, if locks are required, the subordinate acquires the locks.
  2. Decision: if all subordinates say โ€œyes,โ€ the coordinator tells them to commit; otherwise, it tells them to abort. Finally, subordinates reply with โ€œack.โ€

This allows any subordinate to abort a transaction. To safeguard against crashes, each node can keep a log of messages it sent and receivedโ€”each of these is a decision it needs to remember; these provide enough information for the nodeโ€™s recovery procedure.

The only issue is that if the coordinator crashes after subordinates send โ€œyes,โ€ the subordinates are blocked until the coordinator restarts and responds. The key issue here is that receiving a decision and executing the transactions is done in the same second stage; for example, if the coordinator only sends a message to one subordinate before crashing, the others cannot distinguish that action the subordinate took and can only wait.

Three-Phase Commit (3PC)

Three-phase commit fixes this by making sure all subordinates know the decision before executing anything:

  1. Voting: like before, subordinates respond to a โ€œprepareโ€ with โ€œyesโ€ or โ€œno.โ€
  2. Precommit: if there is a โ€œno,โ€ coordinator sends โ€œabort.โ€ Otherwise, it sends โ€œprecommitโ€ to at least subordinates, and each subordinate responds with โ€œack.โ€
  3. Commit: after receiving โ€œacks,โ€ the coordinator sends โ€œcommitโ€ to each subordinate. Subordinates reply with โ€œack.โ€

Now, if the coordinator crashes before it sends its decision to subordinates, the subordinates can safety abort because it knows no subordinates have already executed the transaction (unless more than nodes fail).