在我们深入探讨 Axon 如何处理一致性之前,我想在 CQRS 作为一个概念的背景下指出一些事情。
对于与 CQRS 结合使用的一致性存在很多误解。最终一致性的概念适用于您在应用程序中定义的不同模型。例如,命令模型最近可能已更改状态,但查询模型尚未反映该状态。查询模型最终与命令模型一致。但是,该查询模型中的信息本身仍然是一致的。
更重要的是,这使您可以有意识地选择一致性的重要性和可以放松的地方。通常,命令模型会做出一致性很重要的决策。您需要确保每个决定都是在了解最近更改的相关知识的情况下做出的。这就是聚合的目的。聚合将始终做出与其状态一致的决策。
我建议阅读响应式原则文档 [1],即第 V 节 [2]。
然后是轴突。 Axon 非常严格地实现了 DDD 和 CQRS 的概念。一致性在聚合中是神圣的。例如,当使用事件溯源时,具有聚合流的事件保证是基于包含该流中所有先前事件的状态生成的。换句话说,流中的事件编号 9 是在知道事件编号 0 到 8 的情况下创建的。保证。
发布活动时,这并不意味着任何预测都是最新的。这可能需要几毫秒。在这里放宽一致性允许我们扩展我们的系统。唯一的缺点是用户可能执行命令、执行查询但还看不到结果。这实际上在系统中比您想象的要普遍得多。有许多方法可以防止这成为问题。实时更新用户界面是一种强大的工作方式。然后,哪个用户进行了更改并不重要;他们几乎立刻就看到了。
反过来可能会带来挑战。用户通过查询观察系统状态。这可能(并且总是会,即使没有 CQRS)提供过时的数据;数据可能在用户观看时已被更改。用户决定进行更改。然而,与此同时,信息已经发生了变化。如果用户知道,这种其他更改可能永远不会提交该命令。
在 Axon 中,您可以使用冲突解决程序来检测这些“看不见”的并行操作。您可以使用传入事件中的“聚合序列”并将它们与您的投影一起存储。如果用户操作导致针对该聚合的命令,则将聚合序列作为预期聚合版本传递。如果实际 Aggregate 的版本与此不匹配(因为同时它已被更改),您可以确定这是否有问题。参考指南 [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