Managing Distributed Transactions
1. Two-Phase Commit Pattern
| Phase | Action |
|---|---|
| 1. Prepare | Coordinator asks all participants to prepare; each votes commit/abort |
| 2. Commit/Abort | If all voted commit → coordinator says commit; else abort |
| Pros | Strong ACID across resources |
| Cons | Blocks on coordinator failure; poor scalability; not internet-friendly |
Warning: Avoid 2PC across microservices — prefer Saga. 2PC is acceptable only within a single trusted infrastructure (e.g., XA across DBs in same DC).
2. Three-Phase Commit Pattern
| Phase | Action |
|---|---|
| 1. CanCommit | Vote phase |
| 2. PreCommit | Acknowledge readiness; participants prepare locally |
| 3. DoCommit | Final commit |
| Improvement | Reduces blocking on coordinator failure |
| Cost | More messages; still assumes synchronous network |
3. Try-Confirm-Cancel Pattern
| Phase | Action |
|---|---|
| Try | Reserve resources (e.g., hold inventory, freeze funds) |
| Confirm | Apply the change atomically using reservation |
| Cancel | Release reservation if any participant fails |
Example: TCC Inventory
// Try
ReservationId r = inventory.reserve(productId, qty, ttl=30s);
// Confirm
inventory.confirm(r);
// or Cancel (auto-expires after TTL)
inventory.cancel(r);
4. Reservation Pattern
| Aspect | Detail |
|---|---|
| Definition | Tentatively hold resource; commit or release later |
| TTL | Auto-release after expiry to avoid leaks |
| Examples | Hotel room hold, seat selection, OAuth authorization code |
5. Saga Pattern vs 2PC
| Choose | When |
|---|---|
| 2PC | Single trust boundary; ACID essential; small participant count |
| Saga | Microservices; high scale; tolerant of eventual consistency |
6. Compensating Transaction Pattern
| Rule | Detail |
|---|---|
| Inverse Effect | Semantically undoes a committed step |
| Recorded | Logged for audit and replay |
| Idempotent | Safe to retry |
| Best-Effort | Side-effects (emails) may be irreversible |
7. Outbox Pattern
| Aspect | Detail |
|---|---|
| Purpose | Atomically commit business state + intent to publish event |
| Mechanism | Insert into outbox table in same DB tx |
| Relay | Polling publisher OR CDC tail forwards to broker |
| Solves | Dual-write problem (DB + broker) |
8. Transaction Coordinator Pattern
| Responsibility | Detail |
|---|---|
| Tracks Tx State | Durable record of in-flight tx |
| Drives Phases | Prepare/commit (2PC) or saga steps |
| Recovery | On crash, reads log and resumes |
| Examples | Atomikos, Bitronix (XA); Temporal, Camunda (saga) |
9. Distributed Lock Pattern
| Property | Requirement |
|---|---|
| Mutual Exclusion | Only one holder at a time |
| Lease/TTL | Auto-release if holder dies |
| Fencing Token | Monotonic ID to prevent stale-lock writes |
| Tools | Redis Redlock, ZooKeeper, etcd, Consul |
Example: Redis Lock
// SET key value NX PX 30000
String token = UUID.randomUUID().toString();
boolean acquired = redis.set("lock:order:123", token, "NX", "PX", 30000);
try {
if (acquired) doWork();
} finally {
// Release only if we still own it (Lua script)
redis.eval("if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) end",
1, "lock:order:123", token);
}
10. Fencing Token Pattern
| Aspect | Detail |
|---|---|
| Definition | Monotonically increasing token issued with each lock acquisition |
| Use | Resource server rejects writes with stale (smaller) token |
| Solves | GC pause / network delay causing stale lock holder to write |