Metadata Card
- Prerequisites: Chapter 13 (Microservices Migration); Understanding ACID transactions
- Estimated Time: 50 minutes
- Core Difficulty: Advanced
- Completion Milestone: Design Saga (choreography/orchestration), understand CQRS and Event Sourcing use cases
Your Progress
Micro-engines are running. Each engine has its own data warehouse — Score Engine has its own ledger, Match Engine has its own match records.
Now your "create tournament" flow needs to: write a record in Match Engine, notify Score Engine to initialize scores for participants. In the single-machine era, add a lock. Now it spans two independent engines and two ledgers. Your Task
Distributed data consistency isn't a "should I use ACID" question — in distributed environments, traditional ACID transactions are either unavailable or too expensive. This chapter covers four common patterns.
Required reading: Saga (orchestration), Transactional Outbox Selective: CQRS Advanced: Event Sourcing
First Layer: Saga — Long-Running Transaction
Break a large transaction into a series of local transactions, each within its own service. If a step fails, execute compensating actions.
Choreography Saga: Each service publishes events triggering the next step. No central coordinator.
Orchestration Saga: An orchestrator tells each service what to do, manages compensation centrally.
Second Layer: CQRS — Command Query Responsibility Segregation
Separate read models from write models. Write uses one model (commands), read uses another (often pre-joined materialized views).
Third Layer: Event Sourcing
Store events, not current state. Current state is computed by replaying events. Provides full audit trail and time travel capabilities.
Fourth Layer: Transactional Outbox
Write the message to a database "outbox" table within the same transaction as the business operation. A separate process reads from the outbox and sends to the message queue.
CREATE TABLE outbox_messages (
id UUID PRIMARY KEY,
event_type VARCHAR(100) NOT NULL,
payload JSONB NOT NULL,
status VARCHAR(20) DEFAULT 'PENDING',
retry_count INT DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);Common Pitfalls: Incomplete Saga compensation, CQRS read model lag, Event Sourcing schema evolution, Dead Letter not handled in outbox.
Traveler's Notes
Cross-service data consistency is a long war — Saga replaces rollback with compensation, CQRS arms reads and writes differently, Event Sourcing makes events a time capsule, Outbox ensures messages don't get lost. No silver bullet, but patterns to follow.
Next: Deployment & Operations Patterns (Chapter 16).