Four patterns for handling transactions across multiple services, demonstrated with a concrete Order → Payment → Inventory flow.
| Package | Pattern | Description |
|---|---|---|
twopc |
Two-Phase Commit | Coordinator + participants, explicit prepare/commit/rollback |
choreography |
Saga (Choreography) | Event-driven, services react to each other |
orchestrator |
Saga (Orchestrator) | Central brain sends commands, tracks state machine |
outbox |
Transactional Outbox | Atomic write + reliable event publishing |
- Java 17+
- Maven 3.8+
mvn testmvn compile exec:javaThree services. One order flow:
Customer places order
│
▼
OrderService ─── creates order (PENDING)
│
▼
PaymentService ─── charges customer
│
▼
InventoryService ─── reserves stock
│
▼
OrderService ─── confirms order (CONFIRMED)
If any step fails, the previously completed steps must be undone.
2PC: Strong consistency. Works only when all services share the same coordinator. Breaks when the coordinator crashes between commits (inconsistent state, no auto-recovery).
Saga Choreography: Services publish events and react to each other's events. No central coordinator. Compensation logic is distributed across services. Hard to follow the full flow just by reading one service.
Saga Orchestrator: One orchestrator holds the entire saga logic and state machine. Easier to trace. Compensation is explicit and in one place. The orchestrator itself must be fault-tolerant.
Outbox Pattern: Solves the dual-write problem both Saga approaches have. Write business data and the outbox event in one atomic DB transaction. A background publisher delivers the event reliably with retries.