c# - CQRS模式如何保证消息的顺序

标签 c# domain-driven-design cqrs

我在 Greg Young's sample application 上做了一些调整并在多线程环境中偶然发现了一个问题,即总线中消息的顺序可能无法保证,或者一个事件的处理可能在下一个事件到达之前未完成。

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

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

我必须创建一个 Saga 还是有其他方法可以做到这一点?

最佳答案

您应该选择一种消息传递基础架构,以保证在每个消费者的基础上按顺序传递事件,即使多个线程并行传递给不同的消费者也是如此。也就是说,如果您在发送端按顺序提供事件,消费者将按顺序接收它们。

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

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

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

关于c# - CQRS模式如何保证消息的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34048444/

相关文章:

serialization - 用于 NEventStore 的 Protobuf-net 序列化器 3+

amazon-web-services - 使用Kinesis进行事件来源-重放和持久性

microservices - 需要使用/Cosmos DB 抵御对事件溯源架构的古怪挑战

domain-driven-design - Entity framework 4.0 + POCO + WCF 在DDD中的位置 "world"

c# - 使用 LINQ,我如何选择特定索引处的项目?

c# - ASP.NET 应用程序无法在 Win 10 和 IIS 10 上启动 - HTTP 错误 403.14 - 禁止访问

c# - 如何使用 C# 实现 Modbus 功能 20?

c# - System.Net.Mail.SmtpClient 在 4.7 中是否已过时?

java - DDD 模式中服务 "Helper Classes"的单元测试约定

php - 对于 PHP 中的 DDD,我们如何准确保护非根聚合中实体上的方法?