← Concepts

阅读中文版本

Two-Phase Commit

Two-phase commit coordinates an atomic commit across multiple databases, at the cost of blocking, coordinator failure, and operational complexity.

data-consistency

Definition

Two-phase commit (2PC) is a protocol in which a coordinator asks every participant to prepare a transaction, then tells them all to commit or roll back. A participant that votes yes must hold locks and be able to commit until it receives the decision. The protocol provides atomic commit across databases, but it can block if the coordinator fails after some participants prepared.

Context and scope

Two-phase commit appears in distributed databases, XA transactions, and systems that must atomically update multiple transactional resources. It is less common in microservice architectures, where sagas and outboxes are often preferred for availability.

Common misconceptions

  • Two-phase commit is non-blocking — participants can wait indefinitely for a coordinator decision
  • It provides high availability — a coordinator failure can leave prepared transactions holding locks
  • It is the default choice for microservices — most service architectures avoid distributed transactions for good reasons

Anti-patterns

  • Using 2PC across services over an unreliable network without a recovery process for in-doubt transactions
  • Holding prepared transactions open while waiting for a human or an external system
  • Mixing 2PC with non-transactional side effects such as sending email

Related concepts

Related examples

Authoritative source

https://www.postgresql.org/docs/current/two-phase.html

Prepare, then commit

The coordinator sends a prepare request. Each participant writes enough information to commit or roll back later, acquires the necessary locks, and votes yes or no. If every participant votes yes, the coordinator writes a commit decision and sends it to all. If any votes no, everyone rolls back. The decision point is the coordinator’s durable log; after it records commit, the transaction must eventually commit everywhere.

BEGIN;
-- perform work on this database
PREPARE TRANSACTION 'order-42';
-- coordinator decides, then:
COMMIT PREPARED 'order-42';
-- or:
ROLLBACK PREPARED 'order-42';

Prepared transactions are visible in pg_prepared_xacts. A participant that prepared and then lost contact with the coordinator holds locks and cannot decide on its own. That is the blocking failure mode. Operational runbooks must detect in-doubt transactions and resolve them with the coordinator’s decision, not by guessing.

The coordinator is a single point of failure

If the coordinator crashes after some participants prepared but before recording a decision, the participants wait. A replicated coordinator with a consensus log reduces the risk, but does not eliminate the latency and lock-holding cost. The protocol assumes participants can be unavailable for a while; long outages can exhaust lock tables and block unrelated work.

When to use it

Use 2PC when multiple transactional resources must commit atomically and the availability cost is acceptable, such as a database migration or a tightly coupled system with a reliable coordinator. The advantage is atomicity; the drawback is blocking, lock contention, and recovery complexity. Compared to a saga, 2PC offers stronger atomicity but lower availability and tighter coupling. Most microservice workflows should prefer local transactions plus an outbox or saga unless the business truly requires a distributed atomic commit.