Event Sourcing

in practice

Who we are Benjamin Reitzammer CTO at Vaamo Finanz AG Johannes Seitz Freelance Software Engineer

Who are you? Before we get started... I have heard about Event Sourcing before

I have been to one of the Event Sourcing/CQRS talks

We do CQRS and/or Event Sourcing at work

We do Domain-Driven Design

This talk ... ... is for you, if you want to ... ... understand the basic idea of ES

... know about the advantages of ES

... learn about the issues that come with ES

... understand when ES is a suitable pattern

Event Sourcing vs Active Record

Event Sourcing vs Active Record We all know Active Record:

Event Sourcing is different Don't save the current state of objects

of objects Save the events that lead to the current state Event : Something that happend in the past.

: Something that happend in the past. E.G.

The advantages of Event Sourcing

The advantages of Event Sourcing Complete log of every state change ever

Unmatched traceability and debugability

Very good performance characteristics

No more mapping objects to tables

Mapping objects to tables is suprisingly hard 143 pages on mapping objects to tables

Recommends using ORM-Tools only for CRUD-heavy applications

Why?

The Object-Relational mismatch

How does Event Sourcing work?

Saving objects Create an event for every state change of the object: Persist this stream of events, preserving event order

Restoring objects Subsequently apply the events from the respective EventStream to a "blank" object instance

Restoring objects

Restoring objects

Restoring objects

Restoring objects

Updating objects val account = accountRepository . get ( 123 ) val modifiedAccount = account . withdraw ( new Euro ( 10 )) accountRepository . save ( modifiedAccount ) What should be persisted?

Deleting objects How do you delete an object? Retroactive Event. An event undoing something that happened in the past

Making Event Sourcing work

Issues encountered in practice Event Sourcing & Command Sourcing confusion

Side-effects on event replay

Reporting and queries

Evolving events

Concurrent writes

Problem: Events vs Command Confusing Event Sourcing and Command Sourcing Event Sourcing Persist only changes in state

Replay can be side-effect free Command Sourcing Persist Commands

Replay may trigger side-effects

Ex: Command case class ChangeOwner ( accountID : UUID , newOwner : String ) extends Command class BankAccountCommandHandler ( repo : BankAccountRepository ) { def handle ( changeOwner : ChangeOwner ) { val accountId = changeOwner . accountID val newOwner = changeOwner . newOwner val account = repo . getAccount ( accountId ) val modifiedAccount = account . changeOwner ( newOwner ) repo . saveAccount ( modifiedAccount ) } }

Problem: Side-effects We don't want side-effects to be replayed E-Mails sent twice, orders placed etc.

Solutions Solution 1: Separate side-effect and state change

Solution 2: Saving event triggers side-effect

Solution 1: Separate side-effect and state change Execute command on object. This triggers side-effects produces events Command -> Object -> Events

Applying Events causes state to change Object -> Event -> Changed Object Only the event (=state change) is being replayed.

Solution 2: Saving events triggers side-effects When events are saved, side-effects are triggered by event-listeners

Problem: Reporting & Queries The persisted event stream does not allow for database queries and reports Solution Use events to create "read models", optimised for queries and reports. Image by Martin Fowler

Problem: Evolving events How to evolve (immutable) events? Reasons for change Event no longer relevant (delete)

Event fields change (edit)

Event names change (rename) Solution Rewrite events in Event Store

Event update at runtime

Snapshotting

Problem: Concurrent writes How to resolve race conditions that occur due to concurrent writes? Simple solution: Optimistic locking

Summary Don't confuse Event Sourcing & Command Sourcing

Decide how to handle side-effects on event replay

Reporting and queries

Versioning of events

Concurrent writes

Considering Event Sourcing

Pros and Cons of Event/Command Sourcing Pros Bypass the O-R impedance mismatch

Easy way to undo things

Debugability and traceability

After-the-fact data analysis of Event Streams Cons Takes getting used to

Much less framework/community/vendor support

Awkward queries (solved by CQRS)

Debugging and accountability Every change to state is traceable

You know how the system got into the current state

Metadata like "who did that" and "when did it happen"

Mining of event streams Mining event streams for information

Example: recommendation engine, recommending items customers removed from their shopping cart

Hunt terrorists by analysing their financial transactions

Should I be doing Event Sourcing? Event Sourcing is probably a good fit when ... you're building rich object-oriented domain models (e.g. DDD)

you have a lot of behaviour that isn't CRUD

accountability/debugability is critical

you need version control/undo for data (e. G. Wikis, Google Docs)

your business derives value or competitive advantage from event data

your domain is inherently event driven (e. G. basketball game tracking)

you're building a scaleable system based on the CQRS pattern

Interesting Projects Event Store Open Source database for Event Sourcing

Works on .Net/Mono

Early version of Java/Scala Bindings available

More Information on geteventstore.com Akka Persistence Experimental extension for Akka

Runs on JVM

More Information available on akka.io

Thank you for your kind attention

/