Distributed Transactions
Distributed transactions span multiple services or databases. The goal is that operations either all succeed or all fail (or reach an acceptable final state). Common patterns: 2PC, TCC, Saga, local message table / transactional outbox. This article explains each pattern and when to use it with a comparison table.
Overview
- 2PC (Two-Phase Commit): Coordinator sends prepare; participants execute and vote. If all OK, commit; else abort. Strong consistency; coordinator is single point, can block; participants hold locks. Suited for short, strongly consistent transactions.
- TCC (Try-Confirm-Cancel): Try reserves resources; Confirm confirms; Cancel cancels. High business intrusion; all three phases must be implemented. Suited when resources can be reserved (accounts, inventory).
- Saga: Long transaction split into local transactions, each with a compensation. On failure, run compensations in reverse order. Eventually consistent; compensation can fail; needs idempotency and retry.
- Local message table / Transactional outbox: Local transaction and message send in one local transaction; consumer processes idempotently. Eventually consistent; simple to implement; depends on MQ.
Example
Example 1: Pattern comparison
| Pattern | Consistency | Complexity | Best for |
|---|---|---|---|
| 2PC | Strong | Medium | Short cross-DB transactions |
| TCC | Strong (at app layer) | High | Reservable resources |
| Saga | Eventual | Medium | Long flows with compensations |
| Local message table | Eventual | Low | Async, decoupled |
Example 2: Saga example
- Order flow: create order → deduct inventory → deduct payment → ship. On failure, compensate: cancel order, restore inventory, refund, cancel ship. Compensations must be idempotent; may need manual intervention.
Example 3: Transactional message (RocketMQ)
- Send half-message → run local transaction → commit/rollback message. Broker delivers on commit; consumer processes idempotently. Guarantees "if local succeeds, message is sent"; eventual consistency.
Example 4: TCC phases
Java// Try: reserve void tryReserve(Order order) { /* reserve inventory, freeze account */ } // Confirm: commit void confirm(Order order) { /* deduct reserved, finalize */ } // Cancel: rollback void cancel(Order order) { /* release reserved */ }
Core Mechanism / Behavior
- 2PC: Coordinator and participants; prepare phase blocks until all vote; commit/abort in second phase. Failure of coordinator or participant complicates recovery.
- Saga: Orchestration (central coordinator) or choreography (each step emits events). Compensation order is inverse of execution order.
- Transactional outbox: Write business row + outbox row in same transaction; separate process reads outbox and publishes to MQ.
Key Rules
- Prefer avoiding distributed transactions: merge services, merge DBs, use async + idempotency. When needed, choose pattern by consistency and business shape.
- Eventual consistency is often practical; design idempotency, compensation, retry, and manual fallback.
- Strong consistency (2PC, TCC) has performance and availability cost; use only when business requires it.
What's Next
See CAP, Consistency Models. See Idempotency Design, Kafka/RocketMQ transactional messages. See Retry/Backoff for compensation and retry.