Two-Phase Commit in System Designing

expert · System Designing

In a distributed database or a microservices ecosystem with multiple databases, ensuring Atomicity —the "A" in ACID, which dictates that a transaction must either fully succeed or completely roll back—is incredibly difficult. You can no longer just run a standard COMMIT statement because the data spans different physical servers over a network. The Two-Phase Commit (2PC) protocol is an atomic commitment protocol used to ensure that a transaction distributed across multiple database nodes commits successfully or aborts entirely. 1. The Core Architecture The protocol relies on a central orchestrator and multiple participants: The Coordinator: The master node that manages the lifecycle of the transaction, collects votes, and makes the final decision. The Participants (Cohorts): The individual distributed database nodes or services that need to write the actual data to disk. As the name implies, the protocol executes the transaction in two distinct, sequential phases: the Prepare Phase and the Commit Phase . 2. The Two Phases Under the Hood Phase 1: The Prepare Phase (Voting) The client initiates a transaction. The Coordinator generates a unique transaction ID and writes it to its local write-ahead log (WAL). The Coordinator sends a PREPARE message over the network to all Participants . Each participant executes the transaction locally up to the point of saving—allocating memory resources, locking the necessary table rows, and writing the changes to its own local transaction log. The Vote: * If a participant successfully locks resources and is ready to commit, it replies with a VOTE_COMMIT (Yes). If a participant encounters a collision, disk failure, or constraint violation, it replies with a VOTE_ABORT (No). Phase 2: The Commit Phase (Execution) The Coordinator reviews the votes. The outcome depends entirely on unanimity: Scenario A: All Votes are "Yes" (Global Commit) The Coordinator writes a COMMIT decision to its local log. It broadcasts a GLOBAL_COMMIT command to all participants. Every participant permanently writes the data to disk, releases its row locks, and sends an ACK (Acknowledgment) back. Once all ACKs are received, the coordinator marks the transaction completed. Scenario B: Any Vote is "No" or a Timeout Occurs (Global Abort) The Coordinator writes an ABORT decision to its local log. It broadcasts a GLOBAL_ABORT command to all participants. Every participant rolls back its local uncommitted changes, releases its row locks, and sends an ACK . No data is modified. 3. The Critical Flaw: The Blocking Problem While mathematically elegant for consistency, 2PC introduces a severe structural liability: it is a strictly blocking protocol. If the Coordinator crashes at the exact millisecond between Phase 1 and Phase 2 (after participants have voted "Yes" but before receiving the global command), the entire system grinds to a halt: The participants are left completely in the dark, wondering whether the transaction should fail or succeed. Because they voted "Yes", they must hold onto their local database row locks indefinitely to prevent data corruption. No other users or backend services can update or modify those locked rows until the coordinator reboots, reads its historical log, and resolves the pending transaction state. This can trigger catastrophic cascading performance bottlenecks across a system.\ 4. Modern Alternative: The Saga Pattern Because of the blocking risks and high network overhead of locking database rows across multiple servers, modern high-scale microservice architectures largely avoid 2PC in favor of the Saga Pattern . Instead of trying to enforce a single global ACID transaction across your entire infrastructure at the exact same second, a Saga breaks the operation down into a sequence of distinct, localized data updates across services. How it handles failures: If Service 1 and Service 2 complete their steps successfully, but Service 3 crashes or rejects the action, the system does not use a database rollback. Instead, it intentionally triggers Compensating Transactions backward down the execution chain—manually executing reverse business actions (e.g., if Service 2 was a charge, the compensating step is issuing an explicit refund) to achieve Eventual Consistency . 5. Structural Comparison Feature Two-Phase Commit (2PC) Saga Pattern Consistency Model Strict Consistency (ACID) Eventual Consistency (BASE) Resource Isolation High (Locks rows until the entire protocol finishes) Low (Changes are visible to other transactions instantly) Performance Impact High network latency and risk of blocking High throughput; asynchronous execution Primary Use Case Clustered relational databases (e.g., CockroachDB internals) Loose microservices, e-commerce checkouts, complex workflows

Back to System Designing

Browse all study material on Careeroza