我理解事务一致性和最终一致性之间的区别。假设我正在开发一个应用程序,其中有三个Microservices,并且有一个消息总线,当提出Integration时,它会在它们之间发送消息,这意味着最终的一致性。例如,Microservice B发布一个集成事件,而Microservice A在两个小时后处理它,因为Microservice B在事件发布时已经关闭,并且消息是持久的--这很好。
按照我的理解,在Microservice内部应该存在事务一致性--聚合A可以发布聚合B感兴趣的域事件,从而引发域事件并在同一事务中执行对数据库的任何更新。
我不明白CQRS如何适应这种事务一致性/最终一致性场景,因为:
关于CQRS,我相信有两种选择:
如果选择了第二个选项,那么我如何保证读取模型最终将与写模型同步?例如,当引发事件时,读取模型可能会下降。
发布于 2018-10-01 07:05:10
CQRS符合最终一致性的概念,为您在只读系统中使用DBMS系统时提供了较低的易受乐观锁攻击的漏洞。将命令和查询分开使您可以进行工作读/写,而不管两者的可用性如何。
1)。如果由于乐观锁定而希望拥有高度可用的端点,则事务一致性是不可取的。
2)。您绝对可以使用消息总线来更新您读取的模型,因为排队的概念并不是上下文间数据同步的同义词。
发布于 2018-10-02 22:07:41
从技术上讲,聚合是DDD中原子性的单位,因此不需要保证通过域事件进行通信的聚合之间的一致性。从埃文的书中:
聚合是一个关联对象的集群,我们将其作为一个单元来处理数据更改。不变量是数据更改时必须维护的一致性规则,它将涉及聚合成员之间的关系。任何跨越集合的规则都不会被期望在任何时候都是最新的.但是,在聚合中应用的不变量将随着每个事务的完成而强制执行。
但是,出于实际目的,我开发的大多数服务都将域事件的处理包装在为处理初始请求而创建的相同环境事务中。分布式应用程序很难设计和调试,而不必担心服务内部的补偿操作!
我目前正在使用MediatR库将域事件处理程序与生成它们的原始命令/请求处理程序分离。它与消息传递系统具有非常相似的发送/处理语义,并包含一个健壮的中间件类管道,用于验证和前后处理。
发布于 2018-10-03 01:50:11
如果选择了第二个选项,那么我如何保证读取模型最终将与写模型同步?
解决方案是两个选项的混合:
这样你就不会输掉比赛了。如果由于任何原因,读取模型不可用,则工作人员将再次重新检查事件。
https://stackoverflow.com/questions/52568922
复制相似问题