Event Sourcing

Currently at sky we are working in a greenfield project. We have decided to use Event Sourcing at that project.

So… what is Event Sourcing? Probably one of the best explanations is this Greg Young video. He is the person that coined the term Event Sourcing.

Essentially, Event Sourcing is treating the state of your application as a set of immutable events. What does this mean?

Statefull vs. Event Sourcing example

Lets look at an example inspired by the one Greg uses on the video. Our customer Peter decides to buy a LED TV and some oranges. Then he decides to drop the led tv before checking out.
For simplicity I will assume that we are using a relational database. It is not a requirement, though.

For an online shopping application, we need to track the shopping cart and eventually checkout. In a traditional application, we would probably have a mutable table in our database that stores the state of the shopping cart.

Initial state
Customer Shopping_cart_id Items
Peter 5123849
Added tv and oranges
Customer Shopping_cart_id Items
Peter 5123849 {“LED TV”, “ORANGES”}
dropped led tv
Customer Shopping_cart_id Items
Peter 5123849 {“ORANGES”}

This is probably not a good relational design but it is simple enough for the example.
Now lets see how the Event Sourcing example could look like.

Initial state
Customer Shopping_cart Item Event_type date_time
Added tv and oranges
Customer Shopping_cart Item Event_type date_time
Peter 5123849 LED TV item_added_event 2016-jun-01T22:50:34
Peter 5123849 ORANGES item_added_event 2016-jun-01T22:50:46
dropped tv
Customer Shopping_cart Item Event_type date_time
Peter 5123849 LED TV item_added_event 2016-jun-01T22:50:34
Peter 5123849 ORANGES item_added_event 2016-jun-01T22:50:46
Peter 5123849 LED TV item_removed_event 2016-jun-01T22:51:30

The key difference between them is that in the traditional application we are always updating a row that represents the state of the shopping cart. On the other hand, in the Event Sourcing example we are always adding events that represent things that happened to the shopping cart.

The events are immutable: once an event row has been added, it is never modified. In the example, we don’t remove the “led tv – item added event”. We simply add an “item removed event”.

Implications

  • Free audit log
  • Lossless data storage
  • CQRS
  • Eventual consistency
  • Event Replay
  • Temporal Query
  • Event reversing
  • No concurrent updating problems

Free audit log: In the example, you know all the actions the user performed (add tv, add oranges, remove tv). Regulators usually love that. Also, support can use it to find out what a customer did and therefore help understanding what went wrong and how to fix it.

Lossless data storage: Every time an application updates a field, it loses information. It loses the previous value of the field. Lets imagine that the business needs a report aggregating “how often did the customers remove items from the shopping cart” or “on average, how much time is elapsed from one time a user adds an item until next time he/she adds another one”. With Event Sourcing, this information has been preserved for all the past shoppings, so we can make the report retroactive. This would be impossible without event sourcing.

CQRS: Command and Query Responsibility Segregation is a way in which an application can relate to a database. When using CQRS, the application has different write and read views of the data. It is very often related to Event Sourcing because in the events world you usually have to make a projection of the data before the read side can use it.

This views are stored in different physical locations. The write store acts like a persistent, immutable repository while the read store is a disposable cache that can be recreated at any moment from the write repository.

In our example, the write side sees the event. Sometimes the application will be interested in finding out what the current state of the cart is, and therefore it will read all the events and replay them into a cart. That way the read and the write side of the app use different models.

Eventual consistency: Usually CQRS systems (and by extension, a lot of Event Sourcing systems) work with eventual consistency. The data is persisted to the write repository and it eventually reaches the read cache, and in the meanwhile in might not be consistent.

Event replay: You can rebuild an object at any time using all the events you have.

Temporal query: Since we can replay all the changes in the system to generate the state of the object at any point in time. For example, we could ask “how was Peter’s cart the 2016-jun-01 at 22:50:00?”. In others systems this might be possible, but often requires ad hoc work. With Event Sourcing this comes for free.

Event reversing: Since we have the historical of the events that happened to the system, we can also reverse them by playing the opposite event. For example, if you want to cancel the last transaction in a bank account, you can look for the event (lets say it is a deposit) and play the opposite one (for example, a withdrawal for the same amount).

No concurrent updating problems: Since data is immutable, you don’t have to worry about things like race conditions. If you have 100$ in your bank account and you receive the events “deposit 30$” and “withdrawal 15$” you are always going to end up with a projection of 115$.

Image: https://en.wikipedia.org/wiki/Geologic_time_scale#/media/File:Geological_time_spiral.png

License: Public domain (US)

Advertisements

One Comment Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s