Basic tutorial on Event Sourcing and CQRS
I recently learned about the Event Sourcing (and CQRS) design patterns. Unfortunately, reading through Martin Fowler’s bliki definition just didn’t help. What helped the most were two things:
CQRS relies on Event Sourcing in order to work.
Event Sourcing requires the following:
- You have an event store in which you store events.
- You have Aggregate Roots, which is a way of structuring data structures so that you can always link the fields and attributes and other associated data with the underlying “root” data structure. For example, the ‘pages’ in a ‘book’ would never change without the ‘book’ data structure knowing that.
Event Sourcing means that every time you change any data — any state, in fact, which also happens to be data — you generate an event.
Matt’s contact manager example application does just that: in all of the methods which change any data, an event is 1. created, 2. filled with the new data, and 3. added to the event store. It’s a little more complicated than that, but only because you also have to take into account the transactional logic necessary when changing data or state.
What’ s interesting about this is that you can then recreate state by “replaying” the events — from the beginning, if you have to. Replaying the events means that all of the incremental changes made are then reapplied after which you get your current state back!
CQRS is a design pattern that makes distributed and concurrent systems easier to design and maintain. The diagram above illustrates the problem particularly well: The user decides what she wants, resulting in a change being acted out on the state. That change then is also translated into an event which updates the report, which the user can then query if she’s curious.
By separating your “write” data model from your “read” data model you can respond to queries much more quickly and you can also make sure to use costly database transactions for operations that need it, for example. You do then run the risk that the data you query is not 100% accurate with regards to when it was queried: your “read” data model is always updated after your “write” data model.
Why am I writing about this? Well, CQRS certainly doesn’t really apply to my work, but Event Sourcing does. Being able to rewind (and re-forward) state is something that I think a BPM engine should do. I’m also curious if Event Sourcing could help when architecting any BPM engines that deal with ACM.