Back to the map

Module 14 · Distributed transactions · Lesson 2 of 5

Two-phase commit

The classic protocol for atomic commit across several resources: a coordinator asks everyone to prepare, and commits only if all vote yes. The two phases, what each participant must log, the blocking problem when the coordinator dies.

DeepShould-knowSenior 12 minVideoPro Updated Nov 2026

The video walkthrough is part of Pro.

See what Pro includes
Video walkthrough · 2:26 · narrated, with captions

Why it matters

Two-phase commit is the protocol that gives true atomicity across resources, and it is the thing people mean when they say "distributed transaction". Understanding it precisely tells you both why distributed SQL databases can offer cross-shard transactions and why you should not run it between microservices. Interviewers ask about it to see whether you know the blocking problem, which is the detail that decides where it belongs.

The idea

A coordinator drives the transaction across participants (databases, queues, any resource manager that can prepare).

  1. 1

    Phase 1: prepare

    The coordinator writes the transaction's participants to its log and sends prepare to each. Each participant does all the work, writes undo and redo records durably, holds its locks, and votes yes (it can commit if told to) or no (it has aborted). A yes vote is a binding promise: the participant must be able to commit even after a crash.
  2. 2

    Phase 2: commit or abort

    If every vote is yes, the coordinator durably logs the commit decision, then tells all participants to commit; each commits, releases locks and acknowledges. If any vote is no or times out, the coordinator logs abort and tells everyone to abort. The coordinator's logged decision is the single point of atomicity.
Coordinatorlogs decisionParticipant AParticipant BParticipant Cprepareyesprepare / yesprepare / yesall yes → log COMMIT → send commit to all
Prepare collects binding yes votes; the coordinator's logged decision is the commit point; participants then commit. Between a yes vote and the decision, participants hold locks and cannot act alone.

Recovery rules

Each party recovers from its log. A participant that crashed before voting aborts. A participant that voted yes and crashed must ask the coordinator what was decided; it cannot decide alone. A coordinator that crashed before logging a decision aborts; one that logged commit re-sends commit to everyone until all acknowledge. These rules make the protocol correct under any single failure, provided the logs survive.

The blocking problem

After voting yes, a participant is in doubt: it holds locks and waits for the decision. If the coordinator crashes (or is partitioned away) at that moment, the participant cannot commit (the coordinator may have decided abort because another participant voted no) and cannot abort (the coordinator may have logged commit). It must wait, possibly indefinitely, holding locks that block other transactions on those rows. This is the fundamental weakness: 2PC trades availability for atomicity, and the coordinator is a single point of blocking. Mitigations are a highly available coordinator (replicated with consensus), participant timeouts with heuristic decisions and operator alerts, and keeping transactions short so the window is small.

Costs

CostWhy
LatencyAt least two round trips to every participant plus several durable log writes before the client gets an answer
Lock durationLocks are held from the start of work through the end of phase 2, far longer than a local transaction
Availability couplingAny participant being slow or down stalls the whole transaction; the coordinator being down blocks everyone in doubt
Protocol supportEvery participant must implement prepare; most external APIs and many message systems do not
Operational burdenIn-doubt transactions need tooling and runbooks to resolve

Where 2PC lives today

Inside a single database spanning shards: Spanner, CockroachDB, TiDB and YugabyteDB run 2PC across range leaders, with the coordinator state itself replicated by Paxos or Raft so it cannot be lost and the blocking problem is reduced to a leader failover. Between databases and queues under one transaction manager via XA, in enterprise Java and .NET systems, usually within one data centre. Kafka's transactional producer uses a 2PC-like protocol with a transaction coordinator for exactly-once across partitions. What these share is homogeneous participants under one operator with a durable, available coordinator.

Where it does not belong

Between independently deployed services, especially across teams or with external providers: participants cannot prepare, locks would be held across network calls between services, and one slow service degrades everything else. There the saga pattern, next, with an outbox for messaging, is the standard.

Two-phase commit · Backplane