我与Greg Young's sample application杂乱无章,并在多线程环境中偶然发现问题,即总线中的消息顺序可能无法保证,或者事件的处理可能在下一次到达之前未完成
因此,ItemCreated消息可能在ItemChangedSomething消息之后发生,或者至少第一条消息未完全处理。这会在"读取端"中导致问题,因为我想更新尚未(可用)的数据。
如何解决这个问题? (假设CQRS适合域设计案例。)
我是否必须创建一个Saga或者还有其他方法吗?
答案 0 :(得分:4)
您应该选择一种消息传递基础结构,以确保按消费者按顺序传递事件,即使多个线程并行传递给不同的消费者。即,如果您在发送方按顺序提供事件,消费者将按顺序接收它们。
然后有两种基本方法来处理这种情况:
基础设施:在没有分布式数据存储的小型CQRS应用程序中,您可以为每个事件记录全局且不断增加的唯一ID。然后确保事件由消息传递体系结构按其id的顺序传递。这将完全消除无序事件传递。同样,您可以记录事件的时间戳,并按照时间戳的顺序交付。虽然这可能会导致某些情况下的竞争条件,但对于大多数应用程序和用例,基于时间戳的排序就足够了(特别是,如果ItemCreated
和ItemChanged
基于人为操作)。
状态机:对于较大(通常是分布式)的设置,您可以使用显式或隐式自动机/状态机模型来应对消息的无序到达。使用适当的消息传递基础结构,如果它们来自同一个流,您将永远不会收到ItemCreated
和ItemChanged
乱序,但可能会发生来自两个不同来源(流/聚合根)的事件由任意投射或传奇以任意顺序消耗。由于这些事件是独立的,因此通常有一种方法(想想状态机)将投影保持在任一订单的有效状态。