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

本文关键字:模式 消息 顺序 CQRS 何确保 确保 | 更新日期: 2023-09-27 18:25:19

我在处理Greg Young的示例应用程序时遇到了一个多线程环境中的问题,即总线中消息的顺序可能无法保证,或者事件的处理可能无法在下一个到达之前完成。

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

如何绕过这个?(假设CQRS适用于领域设计情况。)

我必须创作一个传奇吗?或者有其他方法吗?

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

您应该选择一个消息传递基础设施,该基础设施可以保证按每个使用者按顺序传递事件,即使多个线程并行传递给不同的使用者。也就是说,如果你在发送端按顺序发送事件,消费者就会按顺序接收它们。

然后有两种基本的方法来处理这种情况:

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

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