CQRS and Event Sourcing

Somewhat recently –I have not been blogging much I know— Udi put up a good post (and long) about Command and Query Responsibility Segregation. One point that Udi brought up is that people have tied together Event Sourcing and Command and Query Separation. They are certainly two different patterns but I believe that it is a relatively rare case where two patterns share a symbiotic relationship.

Command and Query Responsibility Segregation enables the use of Event Sourcing on many systems that you would otherwise be unable to use Event Sourcing with. Martin Fowler does a good job of describing the downfall of Event Sourcing for most systems. The basic problem is that it is troublesome for querying data. There is no way you can query your event log for all of the customers with the first name of “Gregory”. This is a huge problem as most systems do need to issue large numbers of often times complex queries. This issue prevents most systems from being able to use Event Sourcing. Command and Query Responsibility Segregation however specifies a separation of the query model, this allows one to use an OLAP system on the read side and to deal with the write side separately. Because there are no longer queries on the write side the largest single downfall of event sourcing has  been quietly removed.

I however stated that the two patterns have a symbiotic relationship. We have seen how CQRS enables Event Sourcing but is CQRS itself better off by using Event Sourcing on the data storage on the right side? The answer is a resounding yes.

Firstly when one uses Event Sourcing with CQRS one can avoid the need for 2pc between the data store and the message queue that you are publishing messages to. This is because the Event Store can be used as both an event store and a queue. Conceptually the Event Store is an infinitely appending file. One can just have a read location that gets updated (chasing the end of the file) and presto you have a queue as well. A side benefit from this is that you also end up with only one disk write for both your storage and your durable queue, this may not initially seem like a big win but when you are trying to build performant systems this can help a lot!

The second and I believe most important area where Event Sourcing really aids CQRS is in the only having a single model. If we were to say use a relational database, object database, or anything else that only keeps current state we would have a slight issue. The issue is that we have two different models that we cannot keep in sync with each other. Consider that we are publishing events to the read model/other integration points, we are also saving our current state with a tool like nhibernate. How can we rationalize that what nhibernate saved to the database is actually the same meaning as the events we published, what if they are not? When we use Event Sourcing we only use our events, they are the only model there is nothing to keep in sync. If there is a problem with the Event Stream that people use to integrate with us, like that we had a bug and never sent an event OUR state will be wrong as well.

Going with this if we fix broken data in our system either through an automatic or manual process the changes will automatically (by necessity) be shipped to anyone who may be integrating with us. This is not necessarily the case when one keeps an model representing current state as someone could feasibly want to change the data that’s in the store without going through the domain (and as such no events would be created).

Another benefit of this is that the data in the originating system will be screwed up as well. Generally speaking the closer you are to the people that are responsible for a set of data the more likely they are to notice that something is wrong. When dealing with integration scenarios it tends to workout that people have a level of trust of data from the other system. Since with a separate model the originating would be correct but the integrated systems would be wrong, there is a lower chance that people would notice that the data was in fact wrong.

I hope this goes a way to explain why Event Sourcing and CQRS really go hand in hand.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

10 Responses to CQRS and Event Sourcing

  1. Pingback: Misusing an ORM

  2. gregyoung says:

    “So you’re saying that by leveraging the event store as a message queue, you can more easily *manually* modify domain state directly in the store.

    That’s a terrible rationale. Firstly, this completely contradicts the strict usage of commands to initiate state changes. Secondly, it reduces the pain of “doing it wrong” and stakeholders and developers will repeatedly be tempted to solve problems one by one rather than systematically. This will only rot the architecture. If a developer can’t manage to reliably implement event notification for administrative data modifications, s/he should not be using CQRS.

    This trade-off (one-time 2pc development cost vs ability to mutate data out-of-band) yields a net negative.”

    Umm no nor I am not sure how you got that out of the post.

  3. Mike McG says:

    So you’re saying that by leveraging the event store as a message queue, you can more easily *manually* modify domain state directly in the store.

    That’s a terrible rationale. Firstly, this completely contradicts the strict usage of commands to initiate state changes. Secondly, it reduces the pain of “doing it wrong” and stakeholders and developers will repeatedly be tempted to solve problems one by one rather than systematically. This will only rot the architecture. If a developer can’t manage to reliably implement event notification for administrative data modifications, s/he should not be using CQRS.

    This trade-off (one-time 2pc development cost vs ability to mutate data out-of-band) yields a net negative.

  4. Joe Balfantz says:

    I’m warming up to CQRS and Event Sourcing (I nearly used a similar pattern two years ago), but I’m curious how you reconstitute a current snapshot of an object through an event log? Here’s an explanation of my question: http://jbalfantz.wordpress.com/2010/03/12/problem-with-event-sourcing-reconstituting-our-objects/

  5. gonzalo.vinas says:

    Nice! Thank You Greg.

  6. GonZa says:

    Nice! Thank You Greg.

  7. GonZa says:

    Nice! Thank You Greg.

  8. Nick says:

    Hi, Greg – I tried commenting this morning but I don’t think it worked so I’ll try again.

    I had assumed that you would use 2pc with msmq or similar to publish events to the query component. Does your solution eliminate the need for such a tool?

    If so, how is the query component notified when events are added?

    Also, what medium do you use for event storage (files, couchdb, database table, etc)?

  9. Nick says:

    So you have the query side reading directly from the event store? Does this mean there’s no need for msmq or similar tool to send the events to the query side?

    If so, how does the query side get notified when there are new events that need to be processed? I guess I had assumed you would need a 2pc, and use msmq or something to publish the events to the query side.

    Also, what do you use for the event store – files, database table, couchdb, etc?

    Btw, thanks for posting again – this cqrs/event sourcing stuff has opened up a lot of topics I realize I knew nothing about.

  10. Rob says:

    Good to see you are still alive :) This reminds me of a certain series of posts on DDDD a while back. I believe at one time you were going to talk a bit more specifically about implementations of such a system, including things like CQRS, Event Sourcing and how you handled rollups, state, etc. I’m sure implementations are very dependent on specific scenarios, but for those of us who haven’t had the opportunity to work on a similar type of system, any examples, however contrived or simplified, are useful.

    Hoping there isn’t as much time between now and the next post as between now and the last….

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>