2015-12-02 23 views
4

我玩弄了一点,并偶然发现多线程环境中的问题,即总线中的消息顺序可能无法得到保证,或者事件的处理可能不会在下一次到达之前完成。如何确保CQRS模式下的消息顺序

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

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

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

+3

我认为读取的模型预测通常是单线程的。因此,争用问题不存在。 – plalx

+0

@plalx你能说说单线程吗? – Hippoom

+1

我同意@plaix:你可以有* n *个预测,但是每个都必须是单线程的,因为事件按时间顺序发生,因此按固定顺序发生。多线程在这种情况下没有意义,因为与特定相关ID相关的事件不会并行发生。 –

回答

3

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

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

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

  • 状态机:对于较大(通常分布)的设置,你可以使用显式或隐式自动/状态机模型,以应付的消息的乱序到来。使用适当的消息传递基础架构,如果源自同一个流,则永远不会收到ItemCreatedItemChanged乱序,但可能发生来自两个不同源(流/聚合根)的事件被任意投影或传奇消耗订购。由于这些事件是独立的,所以通常有一种方式(思考状态机)使投影保持有效状态。

+0

是“国家机器”在这里像一个佐贺? – Beachwalker

+0

我的意思是状态机和基本的计算机科学定义一样,因为你可以在概念和阅读方面都使用这个概念。 –

相关问题