如何确保CQRS模式中的消息顺序

Bea*_*ker 5 c# domain-driven-design cqrs

我玩弄了一下与Greg Young的示例应用程序,并在多threadded环境的消息在总线上的顺序可能无法保证或第二天到达之前可能无法完成事件的处理时的问题绊倒了.

因此,ItemCreated消息可能发生在ItemChangedSomething消息之后,或者至少第一条消息未完全处理.这导致"读取侧"出现问题,因为我想更新尚未(尚)可用的数据.

如何解决这个问题?(假设CQRS适合域设计案例.)

我是否必须创建一个Saga或者还有其他方法吗?

Ale*_*ger 5

您应该选择一个消息传递基础设施,即使多个线程并行地向不同的消费者传递事件,也能保证在每个消费者的基础上按顺序传递事件。即,如果您在发送端按顺序提供事件,消费者将按顺序接收它们。

那么处理这种情况有两种基本方法:

  • 基础设施:在没有分布式数据存储的小型CQRS应用程序中,您可以为每个事件记录一个全局且不断增加的唯一ID。然后确保消息传递架构按照事件 ID 的顺序传递事件。这将完全消除无序事件传递。同样,您可以记录事件的时间戳并按时间戳的顺序传递它们。虽然这可能会在某些情况下导致竞争条件,但对于大多数应用程序和用例,基于时间戳的排序就足够了(特别是,如果ItemCreatedItemChanged是基于人类行为)。

  • 状态机:对于较大的(通常是分布式的)设置,您可以使用显式或隐式自动机/状态机模型来应对消息的无序到达。有了适当的消息传递基础设施,如果它们源自同一流,您将永远不会接收ItemCreatedItemChanged乱序,但可能会发生来自两个不同源(流/聚合根)的事件被某些投影或传奇以任意顺序消耗的情况。由于这些事件是独立的,因此通常有一种方法(想想状态机)可以将投影保持在任一顺序的有效状态。