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