Sunday, October 6, 2013

My understanding of event sourcing

I've been studying event sourcing from a distance for little over a year now; reading online material and going through some of the excellent OS code. Unfortunately, there would be no value introducing it into my current project - it would even be a terrible idea, so I decided to satisfy my inquisitiveness by consolidating and sharing my understanding of the concept.

Domain events

An event is something that happened in the past.

Events are described as verbs in the past tense. For example; amount withdrawn, amount deposited, maximum withdrawal amount exceeded. Listen for them when talking to your domain experts; events are as much a part of the ubiquitous language as commands, aggregates, value objects etc...

Once you've captured a few events, you will notice how these concepts have always implicitly been there, but by making them explicit you introduce a whole new set of power tools to work with.

Event sourcing

Having defined domain events one more time, we can now look at event sourcing. By the name alone, it should be obvious events are going to play the lead role.

In traditional systems, we only persist the current state of an object. In event sourced systems, we don't persist the current state of an object, but the sequence of events that caused the object to be in the current state.

In traditional systems, every time a change happens, we retrieve the old state, mutate it, and store the result as our current state. In this example, only the last column would be persisted.

Old amount Command Current amount
CreateAccount $0
$0 Deposit $2000 $2000
$2000 Withdraw $100 $1900
$1900 Withdraw $500 $1400
$1400 Withdraw $2000 $1400
$1400 Withdraw $300 $1100

In event sourced systems on the other hand, we store the changes that happened - the second column, not the current state. To arrive at the current state again, we take all these events - and replay them.

Command Event Current amount
CreateAccount AccountCreated $0
Deposit $2000 Deposited $2000 $2000
Withdraw $100 Withdrawn $100 $1900
Withdraw $500 Withdrawn $500 $1400
Withdraw $2000 Maximum withdrawal amount exceeded!  $1400
Withdraw $300 Withdrawn $300 $1100

Notice how we already gain better insights into what's happening by seeing an explicit maximum amount exceeded event.

Next time; what does this look like in code?

Feel free to complement and correct my understanding of event sourcing.

7 comments:

  1. Cool. Can't wait to see implementation approach.

    ReplyDelete
  2. would be great if you do it in php :)

    ReplyDelete
  3. can you use jdon to implement it? jdon is a Command and Domain Events java framework: jdon.org

    ReplyDelete
  4. personally I love this seperation, but still in search of ways to have the "event" be the returned result of a webservice receiving the "command".

    ReplyDelete
  5. I still can't get over this great place I recently visited! That place was like seeing a barn. Actually, a barn might sound better! This place is at least thousand times better!

    ReplyDelete
  6. This is cool in theory, but it is very hard to implement anything on this in practice... For example you don't have transactions, just events stored, so you don't know by a conflict or error, how to protect data integrity. By transactions you would simply rollback all of the events contained by the transaction... I don't think event sourcing will ever work, however I think storing the events for backup, archive or migration reasons is a great solution.

    ReplyDelete
    Replies
    1. Storage of events can still be transactional. Using optimistic concurrency you can avoid conflicts.

      Delete