让我们假设我有一个具有内部实体Shape的聚合根Picture。Picture包含形状列表。
Shape仍然是Picture聚合根的内部实体,因为Picture在多个Shape实例之间定义了一些规则。比方说,当Picture是只读的并且Picture可能不包含两个相同颜色的Shapes时,您不能分配新的Shapes。定义了这些规则后,聚合根-了解其所有Shapes -现在可以一致地验证规则。
为了不破坏德米特定律,我总是通过Picture访问Shape。我的问题是与聚合版本控制的优化锁定相关的。如果我通过Picture根聚合来更新Shape的颜色,我是在增加聚集根Picture的版本,还是只增加Shape的版本?
我的假设是-仅限于Shape,因为oposite会阻止一个Picture的多个Shapes的并行更新。
但是,如果在Shape更新期间,Picture被设置为只读模式,该怎么办?
谢谢你的建议。
发布于 2018-06-15 21:07:11
在使用乐观锁定机制时,每当聚合发生变化时,它都应该增加版本号。当聚合的聚合根或任何嵌套实体发生变化时,聚合也会发生变化。当冲突发生时,这意味着之前更快的状态突变已经被提交,并且它不能回滚。这也意味着后来的状态变化是基于旧数据的,必须重新执行。
但是,框架应该通过重新执行命令(load,execute,persist)来透明地重试这种冲突。聚合不应该关心这种情况,域逻辑应该是相同的。换句话说,在冲突的情况下,客户端甚至不应该注意到,HTTP响应(或其他)应该是相同的,可能会稍微慢一点。
发布于 2018-06-15 19:48:42
版本号与聚合相关,因为它是聚合,当形状改变颜色时,聚合的状态会发生变化。我不确定为什么这会阻止并行更新,只要更新实际上没有冲突。
我的意思是,假设我们的AG是版本3,它包含一个红色、黄色和蓝色的三角形。两个命令并行发出,用于将红色三角形更改为绿色三角形,另一个命令用于将蓝色三角形更改为紫色。这两个命令都是在版本3中发出的,因此将检测到并发错误。但假设您使用的是事件,您可以回顾这些事件,并看到它们没有冲突,因此可以允许该过程进行。
我有一篇博客文章对此进行了更详细的介绍。你可以在这里找到它:Handling Concurrency Conflicts in a CQRS and Event Sourced System
我希望这能有所帮助。
发布于 2018-06-15 20:51:37
我的问题与聚合版本控制的优化锁定相关。如果我通过Picture root聚合来更新形状的颜色,我是在增加aggreagate root - Picture的版本,还是只增加形状的版本?
您正在增加根目录的版本。具体地说,您将聚合根从“指向”Shape的version:4更改为指向version:5的根。
这有点类似于git处理文件更改的方式。您编辑了该文件,这意味着以前指向blob:1的文件名现在指向blob:2。但是" file“只是树中的一个名称,因此我们需要将树从名为{ file -> blob:1 }的树更改为名为{ file -> blob:2 }的树,依此类推,直到根。
以另一种方式重复相同的想法,聚合的任何固定版本都是“不可变的”--我应该能够整天查看version:4,并且不会受到您对形状所做的更改的影响,这意味着您的更改需要在新版本中发生。
作为澄清:这很奇怪。
作为一种数据模式,聚合是单个关系图,它会自动变化,以确保保持不变量。但是“对象”想要封装它们自己的状态。因此,我们将单个树拆分成由对象单独管理的片段,然后将它们重新缝合在一起,创建一棵新树。
https://stackoverflow.com/questions/50873959
复制相似问题