domain-driven-designevent-sourcingevent-driven-designaggregates

How should I update copied data in event sourced aggregate?


Contrived example, but say I have an Order aggregate with OrderLine entities. The order line contains cost, quantity and the name of the product. The aggregate is persisted as events to be event sourced. Typically, a single product could have millions of orders.

I now have to update the name of the product. Updating the product aggregate is simple enough but I now have millions of orders with the old product name.

This is a contrived example but assume I need to update this copied state in my orders. What’s the best approach here? Applying the state change to such a huge volume of records seems incredibly expensive operation.


Solution

  • In general, when event sourcing, events are immutable: they represent things that have definitively happened and you can't change the past. If somebody ordered a product "Foo", what is the benefit of later saying they ordered "Bar"?

    There's a minor exception around schema migration, which would likely be an offline process manipulating the event store, after ensuring that anything reading the events can use either the old or the new encoding. This doesn't change the semantic meaning of the events.

    If you really needed to correct every aggregate, new events can be recorded (e.g. removing the old product from an order and adding the new product). This would tend to be done order by order: remember that aggregates tend to define consistency boundaries, so this would be eventually consistent (you could perform arbitrarily many aggregate updates in parallel: event sourced systems tend to be trivially massively parallelizable for that sort of thing).