最终一致性 - 轴突冲突解决者

问题描述

我正在研究 PoC 以评估 Axon 框架在新应用程序开发中的使用情况。

我关心的是与 CQRS 模式的最终一致性,因为一致性是我们的要求。

有很多关于这个主题文章和话题,所以如果我创建了一个重复的话题,我深表歉意。

Axon 提供了一个 conflict resolver,但我不确定它是如何工作的。

我在 open source project 上找到了一个例子。

解决方案将聚合的版本存储在事件存储和读取模型中。客户端将从读取模型中读取版本。 如果我有不同的读取模型,会不会有版本冲突?

Axon 如何解决冲突?

谢谢

解决方法

在我们深入探讨 Axon 如何处理一致性之前,我想在 CQRS 作为一个概念的背景下指出一些事情。

关于与 CQRS 相结合的一致性存在很多误解。最终一致性的概念适用于您在应用程序中定义的不同模型。例如,命令模型最近可能更改了状态,但查询模型尚未反映该状态。查询模型最终与命令模型一致。但是,该查询模型中的信息本身仍然是一致的。

更重要的是,这让您可以在一致性的重要性和可以放松的地方做出有意识的选择。通常,命令模型会做出一致性很重要的决定。您希望确保每个决定都是在了解最近更改的相关知识的情况下做出的。这就是聚合的目的。聚合将始终做出与其状态一致的决策。

我建议阅读响应式原则文档 [1],即第 V 节 [2]。

然后是轴突。 Axon 非常严格地实现了 DDD 和 CQRS 的概念。一致性在聚合中是神圣的。例如,当使用事件溯源时,具有聚合流的事件保证是基于包含该流中所有先前事件的状态生成的。换言之,流中的事件编号 9 是在了解事件编号 0 到 8 的情况下创建的。保证。

发布事件时,这并不意味着任何预测都已经是最新的。这可能需要几毫秒。这里放宽一致性允许我们扩展我们的系统。唯一的缺点是用户可能会执行命令、执行查询但还看不到结果。这实际上在系统中比您想象的要常见得多。有很多方法可以防止这成为问题。实时更新用户界面是处理此问题的有效方法。那么由哪个用户进行更改并不重要;他们几乎立即就看到了。

反过来可能会带来挑战。用户通过查询观察系统状态。这可能(并且总是,即使没有 CQRS)提供陈旧数据;数据可能在用户观看时已被更改。用户决定进行更改。然而,与此同时,信息已经改变。另一个变化可能是,如果用户知道,它就永远不会提交该命令。

在 Axon 中,您可以使用冲突解决程序来检测这些“看不见的”并行操作。您可以使用传入事件中的“聚合序列”并将它们与您的投影一起存储。如果用户操作导致针对该聚合的命令,则将聚合序列作为预期聚合版本传递。如果实际聚合的版本与此不匹配(因为它在此期间已被更改),您可以决定这是否有问题。参考指南 [3] 中有一个简短的解释。

我希望这能说明 CQRS 和 Axon 上下文中的一致性。

[1] https://principles.reactive.foundation

[2] https://principles.reactive.foundation/principles/tailor-consistency.html

[3] https://docs.axoniq.io/reference-guide/axon-framework/axon-framework-commands/modeling/conflict-resolution