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

PatternConsistencyComplexityBest for
2PCStrongMediumShort cross-DB transactions
TCCStrong (at app layer)HighReservable resources
SagaEventualMediumLong flows with compensations
Local message tableEventualLowAsync, 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.