乐观锁定&聚合根的内部实体

时间:2018-06-15 10:42:19

标签: cqrs event-sourcing

假设我有一个内部实体rows, seats = self._aircraft.seating_plan() self._seating = [None] + [{letter:None for letter in seats} for _ in rows] 的聚合根PictureShape包含形状列表。

Picture将仍然是Shape聚合根的内部实体,因为Picture在多个Picture实例中定义了一些规则。假设当Shape为只读且Shape可能不包含两个相同颜色的Picture时,您无法分配新的Picture。定义了这些规则后,聚合根 - 了解所有Shapes - 现在可以一致地验证规则。

为了不制动得墨忒耳法,我总是通过Shapes访问Shape。 我的问题与使用聚合版本控制的ptimistic锁定有关。如果我要更新PictureShape根聚合的颜色,我是否会增加聚合根的版本 - Picture或仅增加Picture的颜色?

我的假设是 - 仅Shape,因为对话会阻止并行更新一个Shape的多个Shapes

但是,如果在更新Picture期间,Shape设置为只读模式会怎样?

感谢您的建议。

3 个答案:

答案 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响应(或其他)应该是相同的,可能更慢。