diagram.mmd — sequence
Two Phase Commit sequence diagram

Two-phase commit (2PC) is a distributed consensus protocol that ensures all participating nodes in a distributed transaction either all commit or all roll back, preserving atomicity across multiple independent databases.

This sequence diagram illustrates the two distinct phases. In Phase 1 (Prepare), a coordinator — typically the application server or a transaction manager — sends a PREPARE message to every participant (each database node involved in the transaction). Each participant checks whether it can commit: it writes the proposed changes to its WAL and acquires necessary locks, then responds VOTE-YES if it is ready to commit or VOTE-NO if it cannot (due to a constraint violation, lock conflict, or resource issue).

In Phase 2 (Commit or Abort), the coordinator collects all votes. If every participant voted YES, the coordinator sends COMMIT to all participants; each participant then finalizes its changes, releases locks, and acknowledges. If any participant voted NO, the coordinator sends ABORT to all participants, and each rolls back its prepared changes.

The critical failure scenario is when the coordinator crashes between Phase 1 and Phase 2. Participants that voted YES are stuck in a "prepared but not yet committed" state, holding locks and blocking other transactions. This is the blocking problem of 2PC — it cannot make forward progress without the coordinator recovering. This vulnerability motivates the Paxos and Raft-based protocols used by systems like Google Spanner.

For developers, 2PC appears implicitly when using XA transactions (supported by MySQL, PostgreSQL, and Java EE), distributed ORMs, or service meshes that coordinate cross-service database writes. The Saga Pattern is a common alternative that avoids 2PC by replacing the distributed transaction with a sequence of local transactions and compensating actions.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

Two-phase commit is a distributed consensus protocol that ensures all nodes participating in a distributed transaction either all commit or all roll back. A coordinator drives two phases: a prepare phase where each participant votes yes or no, and a commit/abort phase where the coordinator broadcasts the final decision based on the collected votes.
In Phase 1, the coordinator sends PREPARE to all participants. Each participant writes its proposed changes to its WAL, acquires necessary locks, and responds VOTE-YES if ready or VOTE-NO if it cannot commit. In Phase 2, if all votes are YES the coordinator sends COMMIT to all participants; each finalises its changes and releases locks. If any vote is NO, the coordinator sends ABORT and each participant rolls back its prepared changes.
Use 2PC when you need strong ACID guarantees across multiple databases and can tolerate the latency of two round-trips plus the risk of blocking during coordinator failure. 2PC is well-supported via XA transactions in MySQL and PostgreSQL. Use the Saga pattern when you need distributed transaction coordination across microservices that own separate databases, where the blocking risk of 2PC is unacceptable and eventual consistency with compensating transactions is sufficient.
The critical failure is coordinator crash between Phase 1 and Phase 2. Participants that voted YES are stuck in a prepared-but-not-committed state, holding locks and blocking other transactions indefinitely. This is the "blocking problem" — 2PC cannot make forward progress without coordinator recovery. In practice this requires persistent coordinator state (so it can recover and replay Phase 2) or an operator to manually abort prepared transactions on participants.
Two-phase commit (2PC) is a distributed protocol for coordinating atomic commit across multiple database nodes. Two-phase locking (2PL) is a single-node concurrency control mechanism where a transaction acquires all locks it needs before releasing any of them, enforcing serializability. The two share a name structure but solve different problems — 2PC is about distributed atomicity, 2PL is about single-database isolation.
mermaid
sequenceDiagram participant Coord as Coordinator participant DB1 as Participant DB1 participant DB2 as Participant DB2 note">Note over Coord,DB2: Phase 1 — Prepare Coord->>DB1: PREPARE (txid=7731) Coord->>DB2: PREPARE (txid=7731) DB1->>DB1: Write to WAL, acquire locks DB2->>DB2: Write to WAL, acquire locks DB1-->>Coord: VOTE-YES DB2-->>Coord: VOTE-YES note">Note over Coord,DB2: Phase 2 — Commit Coord->>Coord: All votes YES — decide COMMIT Coord->>Coord: Write commit decision to coordinator log Coord->>DB1: COMMIT Coord->>DB2: COMMIT DB1->>DB1: Apply changes, release locks DB2->>DB2: Apply changes, release locks DB1-->>Coord: ACK committed DB2-->>Coord: ACK committed Coord-->>Coord: Transaction complete note">Note over Coord,DB2: Abort path (if any VOTE-NO) note">Note over DB1,DB2: Coordinator sends ABORT to all participants
Copied to clipboard