In trying to get my head around CQRS (and DDD in general) I have come across situations when two events occur on different aggregates but the order of them has domain meaning. If so then they could happen so close together that a timestamp (as used by the sample implementations I have seen) cannot differentiate them, meaning the event store doesn't contain a 'complete' representation of the domain as there is ambiguity over the order in which events occurred.
As an example, the domain could fire a CustomerCreatedEvent
which applies to the Customer
aggregate, and then a CustomerAssignedToAgent
event on the Agent
aggregate. The CustomerAssignedToAgent
event doesn't make sense if it occurs before the CustomerCreatedEvent
, but typically both of these might be fired as a result of one operation which makes it likely that the timestamps would effectively be the same.
So am I just modelling things badly? Should there ever be a situation where the sequence of events across different aggregates is important? Or should you keep a global sequence number on your event store, so that you can identify the exact sequence in which events occurred?
Both these patterns are useful, but they do solve different challenges. CQRS is much more common and doesn't need Event Sourcing. Event Sourcing does normally involve CQRS too.
An event source pattern is an approach to a sequence of events. The system stores a history of the changes in data states and notifies a consumer to handle them. In event sourcing, you store the entire chain of data transformations – not just the latest state (or final result) of the data.
Event Sourcing is a pattern for storing data as events in an append-only log. This simple definition misses the fact that by storing the events, you also keep the context of the events; you know an invoice was sent and for what reason from the same piece of information.
Instead of saving latest status of data into database, Event Sourcing pattern offers to save all events into database with sequential ordered of data events. This events database called event store. Instead of updating the status of a data record, it append each change to a sequential list of events.
I also found this post by Greg Young on the domaindrivendesign yahoo list:
Order is only assured per a handler within an aggregate root boundary.
There is no assurance of order between handlers or between aggregates.
Trying to provide those things leads to the dark side.
In general it is bad idea to enforce global order. Aggregates are meant to form ACID-semantics boundaries.
This means that two aggregates should not be updated in one transaction and there is no other means of enforcing global order.
In your case it could make sense that along with creating CustomerCreatedEvent Customer should send a message to Agent aggregate telling it to assign itself. Generally inter-aggregate communication should be done via messaging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With