Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何保证CQRS模式中消息的顺序_C#_Domain Driven Design_Cqrs - Fatal编程技术网

C# 如何保证CQRS模式中消息的顺序

C# 如何保证CQRS模式中消息的顺序,c#,domain-driven-design,cqrs,C#,Domain Driven Design,Cqrs,我在多线程环境中遇到了一个问题,即总线中消息的顺序可能无法保证,或者事件的处理可能无法在下一个到达之前完成 因此,ItemCreated消息可能发生在ItemChangedSomething消息之后,或者至少第一条消息没有被完全处理。这会导致“读取端”出现问题,因为我想更新(尚未)可用的数据 如何解决这个问题?(假设CQRS适用于域设计案例。) 我是否必须创建一个传奇,或者是否有其他方法可以做到这一点?您应该选择一个消息传递基础结构,该基础结构可以保证按每个消费者的顺序传递事件,即使多个线程并行

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

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

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


我是否必须创建一个传奇,或者是否有其他方法可以做到这一点?

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

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

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

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


我认为read模型投影通常是单线程的。因此,不存在争用问题。@plalx您能详细说明单线程吗?我同意@plaix:您可以有n个投影,但每个投影都必须是单线程的,因为事件是按时间顺序发生的,因此是按固定顺序发生的。多线程在这种情况下没有意义,因为与特定关联id相关的事件不会并行发生。传递通常是有序的,但消息总线可能已经无序地从多个线程接收消息(例如,读取使用来自两个独立事件流的消息的投影)@EbenRoux只要您的单线程投影是自治的(不依赖于其他投影的数据),您就可以像您所说的那样并行运行所有投影,但在实践中,是为所有投影使用一个处理线程还是为每个投影使用一个处理线程更常见?是“状态机”这里有点像传奇?我指的是计算机科学基础定义中的状态机,因为你可以在传奇和阅读侧投影中使用这个概念。