HomeArticlesTwo-Phase Commit: How Distributed Databases Agree to Commit or Abort Together

Two-Phase Commit: How Distributed Databases Agree to Commit or Abort Together

Imagine a bank transfer that touches two separate databases: one debits your checking account, the other credits your savings account. What happens if the first update succeeds but the second fails halfway through a network hiccup? Two-phase commit (2PC) is the classic protocol distributed systems use to answer that question, forcing every participating node to agree in lockstep: either everyone commits, or everyone aborts, with no in-between state allowed. It works by splitting the decision into a voting phase and a decision phase, coordinated by a single node that collects votes before issuing a final verdict. The protocol is elegant and widely used, but it carries a well-known fragility: if the coordinator disappears at just the wrong moment, participants can be left frozen, unable to move forward on their own. Understanding 2PC is the first step toward understanding why modern systems increasingly reach for consensus algorithms like Paxos and Raft instead.

mysimulator teamUpdated June 2026≈ 8 min read▶ Open the simulation

The Distributed Atomicity Problem

A single-node database transaction is easy to make atomic: the storage engine either writes all the changes to disk or none of them, and a crash mid-write just gets rolled back on restart. Distributed transactions are harder because the work is split across multiple independent machines, each with its own local disk, its own clock, and its own chance of crashing or losing network connectivity at any moment. If a transaction updates data on three separate database nodes, you need all three updates to succeed together or all three to fail together atomicity across machines even though no single machine can see what the others are doing in real time. Without coordination, a partial failure (node A commits, node B crashes before it can) leaves the system in an inconsistent state: money debited from one account but never credited to another, an order marked as shipped in one service but never recorded as paid in the billing service. This is the core challenge two-phase commit was designed to solve: turning a set of independent, unreliable local decisions into one reliable, shared, all-or-nothing decision. The protocol introduces two roles to make this possible: a coordinator that drives the process and one or more participants that hold the actual data and do the real work of the transaction.

Phase 1: The Prepare and Vote

The first phase of 2PC is a voting round. The coordinator sends a prepare request to every participant, essentially asking, can you guarantee this transaction will succeed if I tell you to commit it later? Each participant then does the actual work of the transaction locally, applying the changes in a way that could still be undone, and critically, writes the outcome to a durable log on disk before responding. This durability step matters enormously: once a participant writes prepare to yes in its log, it is making a binding promise that it can commit later even if it crashes and restarts in the meantime, because it will replay the log and remember its promise. Each participant then replies with a vote: yes/ready meaning it has done the work, locked the necessary resources, and is fully prepared to commit, or no/abort meaning something went wrong, such as a constraint violation, a lock conflict, or a local failure, and the transaction cannot proceed. The coordinator collects every vote before moving forward. This phase essentially converts an uncertain future action into a certain, logged commitment, which is what makes the second phase trustworthy.

Phase 2: The Final Commit or Abort Decision

Once the coordinator has heard back from every participant, it makes the final call using a simple unanimous rule. If all participants voted yes, the coordinator writes its own decision to a durable log and then sends a commit message to every participant, who each finalize the transaction, release their locks, and make the changes permanently visible. If any single participant voted no, the coordinator instead sends an abort message to all participants, and every one of them rolls back the local changes it tentatively applied during phase 1, as if the transaction never happened. This unanimous-vote rule is what delivers atomicity: there is no path through the protocol where some participants commit while others abort, because the coordinator's single decision is broadcast to everyone and every participant is obligated to follow it. Participants acknowledge the final message, and only then does the coordinator consider the transaction fully closed. From the outside, the whole distributed transaction behaves like one atomic operation, even though it touched several independent machines that never directly coordinated with each other.

The Blocking Problem: A Critical Weakness

Two-phase commit reliably guarantees atomicity, but it has a well-known structural flaw called the blocking problem. Consider this scenario: three participants each vote yes during phase 1, writing that promise durably to their logs and locking their resources. The coordinator receives all three yes votes, and is about to send the commit message, but before it can send anything, it crashes, perhaps due to a hardware failure or network partition. Now every participant is stuck in an uncertain state. Each one has promised it can commit, so it cannot unilaterally abort, because the coordinator might have already decided to commit and told some other participant. But it also cannot unilaterally commit, because the coordinator might have been about to send an abort. The only safe option is to keep holding its locks, blocking any other transaction that needs those same resources, and wait for the coordinator to recover and tell it what to do. If the coordinator stays down for an extended period, those locks stay held the entire time, potentially freezing large parts of the system. This single point of failure, where the fate of many participants depends entirely on one coordinator's recovery, is the central criticism leveled at 2PC.

Motivating Three-Phase Commit and Consensus Protocols

The blocking problem directly motivated the search for more fault-tolerant alternatives. Three-phase commit (3PC) was an early attempt to fix it by inserting an additional pre-commit phase, giving participants enough shared knowledge that they can safely make progress on their own even if the coordinator disappears, though 3PC still struggles under network partitions and never saw the widespread adoption 2PC did. The more influential path forward turned out to be consensus algorithms like Paxos and Raft. Rather than relying on a single coordinator whose crash can freeze the whole system, these protocols replicate the decision itself across a cluster of nodes and only require a majority quorum to agree, not unanimous participation from every single node. If one node, even a leader, crashes, the remaining majority can still elect a new leader and keep making progress, because no single machine's failure can block the group indefinitely. This shift, from one fragile coordinator making a binding decision to a resilient quorum reaching agreement together, underlies how modern distributed databases, coordination services like ZooKeeper and etcd, and distributed consensus systems achieve both atomicity and high availability, directly addressing the weakness that classic two-phase commit could never fully escape.

Frequently asked questions

What is the main goal of two-phase commit?

The main goal is atomicity across multiple independent nodes in a distributed transaction: ensuring that every participant either commits the transaction together or every participant aborts it together, with no possibility of some nodes committing while others do not.

What is the difference between the coordinator and a participant?

The coordinator is the single node that drives the protocol, sending prepare requests, collecting votes, and broadcasting the final commit or abort decision. Participants are the nodes that actually hold the data, perform the transaction's work locally, vote on whether they can commit, and follow the coordinator's final instruction.

Why must participants write their vote to a durable log before responding?

Writing the vote durably ensures that if a participant crashes and restarts after voting yes, it can recover its promise from the log and still honor it later, rather than forgetting that it committed to being ready. This durability is what makes the yes vote a binding, trustworthy commitment.

What exactly is the blocking problem in two-phase commit?

The blocking problem occurs when the coordinator crashes after participants have voted yes but before it sends the final commit or abort decision. Those participants cannot safely proceed on their own in either direction, so they must hold their locks and wait, potentially for a long time, until the coordinator recovers.

How do Paxos and Raft avoid the blocking problem that two-phase commit has?

Paxos and Raft replicate decisions across a cluster and only require a majority quorum to agree rather than unanimous participation coordinated by one fragile node. If a leader node fails, the remaining majority can elect a replacement and keep making progress, so no single node's crash can freeze the entire system the way a coordinator crash can in classic two-phase commit.

Try it live

Everything above runs in your browser — open Two-Phase Commit: How Distributed Databases Agree to Commit or Abort Together and change the parameters while it is running. Nothing is installed, nothing is uploaded, the whole model lives in one tab.

▶ Open Two-Phase Commit: How Distributed Databases Agree to Commit or Abort Together simulation

What did you find?

Add reproduction steps (optional)