← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Two-Phase Commit (2PC)

Architecture Advanced
debt(d7/e9/b7/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints note automated detection is 'no', and tools listed (phpstan, datadog) can at best flag XA transaction patterns or observe blocking in production — neither catches the coordinator failure risk or bottleneck at design time. The problem is architectural and typically only surfaces under failure conditions in production.

e9 Effort Remediation debt — work required to fix once spotted

Closest to 'architectural rework' (e9). The quick_fix explicitly states to avoid 2PC entirely and replace with the Saga pattern with compensating transactions. This is not a line-level fix — it requires redesigning the distributed transaction model, implementing compensating transactions across services, potentially introducing an outbox pattern, and rethinking failure handling. This is a full architectural rework.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). 2PC applies across web, cli, and queue-worker contexts and shapes every distributed operation touching multiple databases or services. The coordinator becomes a single point of failure and bottleneck that every future change must account for. The locking requirement during the protocol constrains throughput and service design across the system, though it stops short of b9 since it applies only where distributed transactions are used.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field directly states the trap: developers believe 2PC solves distributed transactions reliably, but it is actually blocking — coordinator failure leaves participants stuck indefinitely. This contradicts the expectation of resilience that motivates using distributed transactions in the first place. The common mistakes reinforce that failure paths are rarely tested and the coordinator bottleneck is routinely underestimated.

About DEBT scoring →

Also Known As

2PC two-phase commit distributed commit

TL;DR

A distributed transaction protocol ensuring all nodes commit or all roll back — providing strong atomicity across multiple databases.

Explanation

2PC is a consensus protocol: Phase 1 (Prepare) — a coordinator asks all participants to lock resources and vote commit/abort. Phase 2 (Commit/Rollback) — if all voted commit, the coordinator instructs commit; any abort triggers a full rollback. 2PC guarantees ACID atomicity across multiple databases but has significant costs: blocking (if the coordinator crashes after prepare, participants remain locked indefinitely), two network round trips per transaction, and reduced throughput. Most modern distributed systems prefer the Saga pattern for long-lived business transactions and accept eventual consistency rather than paying 2PC's availability and latency costs.

Diagram

sequenceDiagram
    participant COORD as Coordinator
    participant P1 as Participant 1 Orders DB
    participant P2 as Participant 2 Payments DB
    Note over COORD: Phase 1 - Prepare
    COORD->>P1: PREPARE
    COORD->>P2: PREPARE
    P1-->>COORD: VOTE YES
    P2-->>COORD: VOTE YES
    Note over COORD: Phase 2 - Commit
    COORD->>P1: COMMIT
    COORD->>P2: COMMIT
    P1-->>COORD: ACK
    P2-->>COORD: ACK

Common Misconception

Two-phase commit solves distributed transactions reliably. 2PC is blocking — if the coordinator fails after phase one, participants are stuck waiting indefinitely. This is why 2PC is avoided in modern distributed systems in favour of sagas and eventual consistency.

Why It Matters

Two-phase commit coordinates atomic transactions across multiple databases or services — ensuring all participants commit or all roll back, preventing partial distributed transactions.

Common Mistakes

  • Using 2PC for high-throughput operations — the coordinator is a bottleneck and failure point.
  • Not handling coordinator failure — if the coordinator crashes between prepare and commit, participants are blocked.
  • Using 2PC when saga or outbox patterns would provide better availability with eventual consistency.
  • Not testing the failure path — 2PC rollback code is rarely exercised and often broken.

Code Examples

✗ Vulnerable
// Distributed transaction without 2PC — inconsistent state on failure:
function transferFunds(): void {
    $bankA->debit($amount);   // Succeeds
    $bankB->credit($amount);  // Network failure — money lost!
}
// 2PC prepare phase: both banks lock funds
// 2PC commit phase: both banks execute if both prepared successfully
// Rollback phase: both debit/credit reversed if either failed
✓ Fixed
// 2PC: coordinator asks all participants to PREPARE, then COMMIT
// Ensures atomicity across distributed resources

// PHP example: transfer across two databases
function transfer(PDO $dbA, PDO $dbB, int $amount): void {
    // Phase 1: PREPARE
    $dbA->beginTransaction();
    $dbB->beginTransaction();

    try {
        $dbA->exec("UPDATE accounts SET balance = balance - $amount WHERE id = 1");
        $dbB->exec("UPDATE accounts SET balance = balance + $amount WHERE id = 2");

        // Phase 2: COMMIT both
        $dbA->commit();
        $dbB->commit();
    } catch (\Throwable $e) {
        $dbA->rollBack();
        $dbB->rollBack();
        throw $e;
    }
}

// 2PC is blocking — prefer Saga pattern for long-running distributed transactions

Added 15 Mar 2026
Edited 22 Mar 2026
Views 73
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 1 ping S 0 pings M 2 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 2 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 9 Perplexity 9 Google 5 SEMrush 5 Ahrefs 4 Scrapy 4 Unknown AI 3 Meta AI 2 ChatGPT 2 Claude 2 Bing 2 Majestic 1 Qwen 1 Sogou 1 PetalBot 1
crawler 47 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
Avoid 2PC in PHP microservices — use the Saga pattern with compensating transactions instead; 2PC requires all participants to stay locked during the protocol which kills throughput
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Distributed transaction across multiple databases or services; XA transactions in PHP; tight coupling requiring all services to succeed or fail atomically
Auto-detectable: ✗ No phpstan datadog
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: File Tests: Update


✓ schema.org compliant