假设我们使用事件源和带有ForwardMatchingInstances的AggregateMember,拥有一个聚合类A,一个实体类B和一个实体类C。
创建了两个聚合A,其ID为aId1和aId2。
我们发送一条命令,将B类的新实体添加到id为bId1的aId1
我们发送一条命令,将ID为bId2的B类新实体添加到aId1
现在由于某种原因,我们希望将一个实体移到另一个聚合中,因为业务逻辑对于类型B的实体具有特定的逻辑(与C相同)。
轴突可以支持吗? ->我们可以将实体bId1移动到聚合aId2而不更改bId1(保持相同的ID,只是移动聚合)。
为此,我将使用传奇来确保:
本应转到aId1并对bId1执行操作的待处理命令会发生什么情况? (除了不再有例外了?)
更改后,bId1的新命令是否发送到聚合aId2(bId1现在位于具有相同实体ID的聚合aId2中)?
答案 0 :(得分:2)
我认为回答这个问题的唯一方法:
轴突可以支持吗? ->我们可以将实体bId1移动到聚合aId2而不更改bId1(保持相同的ID,只是移动聚合)。
带有NO。这不是因为Axon,而是因为CQRS和事件源。您不想在其中发出包含实体状态的事件。 您唯一拥有的就是汇总中“发生了什么”的踪迹。您需要做的是,从业务角度了解“移动”的真正含义。
明智地实施,您通常会将其视为添加和删除(以任意顺序)。万一操作失败(也许添加无效),您将需要能够弥补失败。如果经常会发生故障,那么可以,“保留并确认”方法比“尝试并补偿”方法要好。
在Axon中,您可以使用Saga或仅使用控制器。在后一种情况下,您只需发送命令,然后根据结果发送第二条命令。当第二个命令返回失败时,您可以补偿第一个命令。
请注意,命令绝不会“发送给实体”。根据{{1}}带注释的字段(或您配置的@TargetAggregateIdentifier
使用的任何一种方法)将它们发送到聚合。该字段定义了要加载的聚合实例。然后,一旦加载了Aggregate,Axon将定义该Aggregate中的哪个实体定义实际处理Command的处理程序。
最终评论:很多情况下,这些情况取决于许多特定于域的细节。如果没有有关您要为其构建域或案例的任何信息,就很难明智地回答此类问题。