What Is Two-Phase Commit (2PC)?

Two-phase commit (2PC) is a protocol that coordinates a distributed transaction across multiple independent resources — such as databases, message queues, and caches — so that they all commit or all roll back as a single atomic unit. It guarantees that a transaction spanning several systems never ends up partially applied, even though each system commits its own data independently.

A 2PC transaction has one coordinator (the transaction manager) and two or more participants (the resource managers that hold the data). As the name suggests, the coordinator drives the outcome in two phases.

Phase 1: Prepare

The coordinator asks every participant whether it can commit. Each participant does the work of the transaction, durably records enough to guarantee it could commit later — typically by writing to its transaction log — and then casts a vote:

  • Yes / prepared — the participant promises it can commit if asked, and holds its changes and locks until it hears the final decision.
  • No / abort — the participant cannot commit.

Once a participant has voted yes, it gives up the right to abort on its own; it must wait for the coordinator's decision.

Phase 2: Commit or Roll Back

The coordinator collects the votes and makes a single global decision:

  • If every participant voted yes, the coordinator records a commit decision and tells all participants to commit. Each finalizes its changes and releases its locks.
  • If any participant voted no — or failed to respond — the coordinator tells everyone to roll back, and each undoes its prepared work.

Because no participant finalizes anything until all of them have agreed during the prepare phase, the group stays consistent. This is the defining all-or-nothing guarantee of a distributed transaction.

The Blocking Problem

2PC's safety comes at a cost: it is a synchronous, blocking protocol. Between voting yes and receiving the final decision, a participant sits in a "prepared," or in-doubt, state — holding locks it cannot release. If the coordinator crashes at that moment, the prepared participants can be stuck waiting until it recovers, which reduces availability and throughput.

Variations such as three-phase commit (3PC) attempt to reduce this blocking, and many distributed systems avoid 2PC altogether in favor of consensus protocols like Paxos and Raft, or looser patterns such as the saga and outbox patterns, which trade strict atomicity for higher availability.

Two-Phase Commit, XA, and Valkey/Redis

Two-phase commit is the protocol behind XA transactions: the X/Open XA standard defines the contract a resource implements to take part in a 2PC, exposed in Java as the XAResource interface — with its prepare, commit, and rollback operations — and coordinated by a JTA transaction manager.

Native Valkey and Redis transactions run on a single node and do not use two-phase commit. Redisson, the Valkey and Redis Java client, bridges that gap with its RXAResource implementation, letting a Valkey or Redis operation participate in a 2PC distributed transaction alongside a database or message broker. This capability is part of Redisson PRO.

For a hands-on guide with code, see How to Manage Transactions in Valkey and Redis on Java.