假设我有一个内部实体rows, seats = self._aircraft.seating_plan()
self._seating = [None] + [{letter:None for letter in seats} for _ in rows]
的聚合根Picture
。 Shape
包含形状列表。
Picture
将仍然是Shape
聚合根的内部实体,因为Picture
在多个Picture
实例中定义了一些规则。假设当Shape
为只读且Shape
可能不包含两个相同颜色的Picture
时,您无法分配新的Picture
。定义了这些规则后,聚合根 - 了解所有Shapes
- 现在可以一致地验证规则。
为了不制动得墨忒耳法,我总是通过Shapes
访问Shape
。
我的问题与使用聚合版本控制的ptimistic锁定有关。如果我要更新Picture
到Shape
根聚合的颜色,我是否会增加聚合根的版本 - Picture
或仅增加Picture
的颜色?
我的假设是 - 仅Shape
,因为对话会阻止并行更新一个Shape
的多个Shapes
。
但是,如果在更新Picture
期间,Shape
设置为只读模式会怎样?
感谢您的建议。
答案 0 :(得分:1)
版本号与聚合有关,因为当形状改变颜色时,状态被改变的聚合。只要更新实际上没有冲突,不确定为什么这会阻止并行更新。
我的意思是说我们的AG是版本3.它包含一个红色,黄色和蓝色三角形。并行发出两个命令以将红色三角形更改为绿色三角形,并发出另一个命令以将蓝色三角形更改为紫色。这两个命令都是在版本3发出的,因此将检测到并发错误。但假设您正在使用事件,您可以回顾这些事件并看到它们没有冲突,因此可以允许该过程通过。
我有一篇博文,其中详细介绍了这一点。您可以在此处找到它:Handling Concurrency Conflicts in a CQRS and Event Sourced System
我希望有所帮助。
答案 1 :(得分:1)
我的问题与使用聚合版本控制的ptimistic锁定有关。如果我通过Picture根聚合更新Shape的颜色,我是否增加了aggreagate root的版本 - 图片或仅限于Shape?
您正在增加root的版本。具体来说,您要将聚合根从“指向”version:4
的形状更改为指向version:5
的聚合根。
它有点类似于git处理文件更改的方式。您编辑了该文件,这意味着用于指向blob:1的文件名现在指向blob:2。但是“file”只是树中的一个名称,因此我们需要将树从显示{ file -> blob:1 }
的树更改为显示{ file -> blob:2 }
的树,以此类推,直到根目录。
以另一种方式重复相同的想法,聚合的任何固定版本都是“不可变的” - 我应该能够整天查看version:4
,而不会受到您对其所做的更改的影响形状,这意味着您的更改需要在新版本中进行。
作为澄清:这很奇怪。
作为数据模式,聚合是一个单独的关系图,它以原子方式改变,以确保维持不变量。但“对象”想要封装自己的状态。因此,我们采用单个树的一些东西,将其分解为由对象单独管理的碎片,然后将它们再次拼接在一起以创建一个新的树。
答案 2 :(得分:1)
每次聚合变异时,都应该在使用乐观锁定机制时增加版本号。当Aggregate的Aggregate根或任何嵌套实体发生变异时,它会发生变异。当发生冲突时,这意味着先前更快的状态变异已经提交,并且无法回滚。这也意味着后来的状态变异基于旧数据,必须重新执行。
但是,框架应通过重新执行命令(load,execute,persist)来透明地重试此冲突。 Aggregate不应该关心这种情况,域逻辑应该是一样的。换句话说,如果发生冲突,客户端甚至不应注意,HTTP响应(或其他)应该是相同的,可能小更慢。