Conflict Detection and Resolution in an Event-Sourced System (DDD EU 2020 talk summary)
There are well-established patterns for dealing with conflicting updates in traditional data stores (Relational, Key-value) but how do you deal with conflicts when you have event streams?
Event sourcing is not a top level architecture it is a tactical pattern, (unlike EDA)
Event stores act similar to Escrow.
The level of granularity for concurrency is the event sequence
This means I want to write this sequence of events IFF there have been no changes (version / sequence is still the same for this stream / aggregate)
But sometimes you don’t care (can use Expected version ANY if you have no conflicting events (are commutative)) — you just append (avoid deadlocking and retries)
Optimistic concurrency exceptions should most of the time be retried.
You can do an additional check/optimisation (eg. if concurrency ex occurs, check if committed events are the same as the ones we tried to persist. If yes, just return success)
With this kind of concurrency checking (optimistic), what event stores give you is to put some of the conflict resolution logic to the application itself.
For “very hot” streams (eg. trading) a solution is to do this in-memory against a single aggregate instance
Don’t store sequence numbers inside of the events (we only need it to know what it was) — it should be handled by the event store implementation.
There are a lot of the examples out there that mask themselves as Event Sourcing but are actually Event Streaming
Event streaming CAN be used with Event sourcing, in order to distribute events for further processing
Event sourcing is a private persistence strategy - avoid publishing your private persistence schema (you need to have public events in addition to your internal events)
EDA is an enterprise architecture
- Uses message bus
- Decouples producers from consumers
- can be used with event sourcing to distribute events for further processing (again, mind your private schema)
How does CQRS relate to event-sourcing
Applications tend to query more than to write
Replaying events to answer queries is rarely optimal, we instead produce specialized read models
There is a slack for ddd-es-cqrs