Update multiple aggregates in the same handler in a CQRS system

2,781 views
Skip to first unread message

David Reynolds

unread,
Jun 16, 2017, 10:07:32 AM6/16/17
to DDD/CQRS
I have been trying to figure out if it's acceptable to update multiple event sourced aggregates in the same command handler. 

If I have a use case for a customer to able to place an order.  Part of placing an order is that the Customer and Order aggregates are updated.  I can see at least two approaches to this in CQRS (this is only an example scenario).

1.  The UI sends a PlaceOrder command.  A command handler loads the customer aggregate and calls a method to create an order.  The aggregate is saved and emits an OrderCreated event.  This event is handled by a "process manager" that sends something like CreateOrder command.  This is handled and an Order aggregate is created and saved.

2.  The UI sends a PlaceOrder command.  A command handler loads the customer aggregate and calls a method to place an order.  This could return an Order aggregate, or the command handler could create an Order.  The Customer and Order are then both saved in the same "unit of work".

Option 2 is how I've done it in the past when building systems with domain services and Entity Framework.

Any ideas would be appreciated.

Fabian Schmied

unread,
Jun 18, 2017, 3:59:25 AM6/18/17
to DDD/CQRS
The idea of aggregates in CQRS (and really Domain-Driven Design) is to model them in such a way that it is not usually necessary to update two aggregates in order to process a single command. This is the foundation of the benefits to scalability CQRS provides.

So, the first thing you should do is rethink your requirements and your aggregate boundaries (see also, e.g., http://cqrs.nu/Faq/aggregates). For example, why does the Customer need to be updated when a new order is placed? Is this just for display purposes - then you should really handle that in the read model - or are there real business invariants that need to be guarded by the Customer aggregate? Is there an alternative aggregate design that could support your use cases (e.g., without me knowing your domain, would one CustomerOrders aggregate for all the orders of a customer rather than one Order aggregate per order be feasible)?

After doing that, if you still need to update two aggregates, your approach #1 would usually be the way to go in the CQRS architecture. 

When you don't need the scalability options of CQRS, you could of course still implement approach #2, as may be the simpler way to go. However, this means:
- you probably need to update both aggregates in the same "event store transaction" to avoid the risk of inconsistencies - this might not actually be supported by your event store implementation, as event stores usually model transactions around single streams (corresponding to single aggregates)
- the transactional dependency between the two aggregates means you'll lose the possibility of placing them in different, independent event store partitions (restriction with regards to sharding)
- you'll lose the architectural guidance of designing your aggregates as true protectors of invariants (as you can always just update two aggregates without needing to rethink aggregate boundaries)
- you'll increase the likelihood of concurrency conflicts (e.g., placing an order would now conflict with someone updating customer details at the same time)

Best regards,
Fabian
Reply all
Reply to author
Forward
0 new messages