Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure the order of messages in CQRS pattern

I juggled a bit with Greg Young's sample application and stumbled upon the problem in a multi-threadded environment that the order of messages in a bus might not be guaranteed or the processing of an event might not be completed before the next arrives.

Because of this, the ItemCreated message might occur after the ItemChangedSomething message, or at least the first message is not processed completely. This leads to problems in the "read side", because I want to update data that is not (yet) available.

How to go around this? (Assuming CQRS fits for the Domain Design case.)

Do I have to create a Saga or is there some other way of doing this?

like image 902
Beachwalker Avatar asked Sep 26 '22 01:09

Beachwalker


1 Answers

You should choose a messaging infrastructure that guarantees delivery of events in-order on a per-consumer basis, even if multiple threads are delivering in parallel to different consumers. I.e., if you feed the events in order on the sending side, consumers will receive them in-order.

Then there are two basic approaches to handle this situation:

  • Infrastructure: in a small CQRS application without distributed data storage, you can record a global and increasing unique id for each event. Then make sure events are delivered by the messaging architecture in order of their id. That will completely eliminate out-of-order event delivery. Similarly you can record the time stamp of events and deliver them in order of their time stamp. While this might cause race conditions for some cases, for most applications and use cases time stamp based ordering is sufficient (in particular, if ItemCreated and ItemChanged are based on human actions).

  • State machines: For larger (typically distributed) setups, you can use an explicit or implicit automata/state machine model to cope for out-of-order arrival of messages. With a proper messaging infrastructure, you'll never receive ItemCreated and ItemChanged out of order if they originate from the same stream, but it might happen that events from two different sources (streams/aggregate roots) are consumed by some projection or saga in arbitrary order. Since these events are independent, there usually is a way (think state machine) to keep the projections in a valid state for either order.

like image 120
Alexander Langer Avatar answered Oct 03 '22 20:10

Alexander Langer