Domain driven design 基于聚合状态更改的聚合批量更新

Domain driven design 基于聚合状态更改的聚合批量更新,domain-driven-design,cqrs,Domain Driven Design,Cqrs,我正在开发一个事件源应用程序,它遵循DDD和CQRS原则,允许发布广告来销售商品 有一个特定的不变量,我正在尝试建模,它似乎涉及到AR的批量更新,我真的不知道如何去做 不变量如下所示: 会员可以发布广告 会员可能被管理员禁止 如果会员被禁止,其广告必须暂停 出于讨论的目的,广告需要有一个状态,因为会员可以通过点击广告购买商品,所以了解广告是否处于活动状态很重要 我已将我的聚合根设计为: 成员 广告 命令 成员可以是买方或卖方,这取决于上下文,因此我根据需要装饰成员对象 当广告发布时,它们

我正在开发一个事件源应用程序,它遵循DDD和CQRS原则,允许发布广告来销售商品

有一个特定的不变量,我正在尝试建模,它似乎涉及到AR的批量更新,我真的不知道如何去做

不变量如下所示:

  • 会员可以发布广告
  • 会员可能被管理员禁止
  • 如果会员被禁止,其广告必须暂停
出于讨论的目的,广告需要有一个状态,因为会员可以通过点击广告购买商品,所以了解广告是否处于活动状态很重要

我已将我的聚合根设计为:

  • 成员
  • 广告
  • 命令
成员可以是买方或卖方,这取决于上下文,因此我根据需要装饰成员对象

当广告发布时,它们当然会被插入到阅读模型中

现在,当一个成员被禁止时,该成员会触发一个相关事件。 MemberwasBanked(MemberId)

我的问题是,我如何找到该会员拥有的所有广告,并将其暂停

虽然我可以依靠会员状态进行购买交易,但重要的是广告要跟踪其状态,因为还有其他类似的操作可能会触发向会员发送电子邮件,表明其广告因某种原因被暂停

因此,经过大量思考后,我最好的方法是创建一个长时间运行的流程,在这个流程中,我为MemberWasBanked创建一个处理程序,然后在read模型中查找他的活动广告,并发出命令逐个挂起它们


我错过什么了吗?我曾想过使用流程管理器,但读到不应该从PM访问读取端。在任何情况下,PM在大多数情况下决定发送给AR的命令


我遗漏了什么吗?

如果你有一个消息机制,也许你可以“爆炸”MemberwasBanked事件

通过您的消息传递管道发布MemberwasBankind(或等效)事件,并从处理广告的上下文中订阅该事件。当在您的消息传递机制中接收到该事件时,您可以将其分解为多个Disabled事件,这些事件也将通过您的消息传递系统发送,他们每个人都针对一个被禁止成员的当前广告

因此,当消息传递机制处理这些事件时,它们中的每一个事件都将仅写入单个聚合(每个ad,禁用它)


同时,被禁止的用户将阻止进一步插入广告,因此您在这方面也将是安全的。

谢谢Pedro,这是一个好方法,但问题仍然是,虽然我知道会员ID,但我无法获得广告ID,因为当会员发布广告时,我将会员ID记录在广告聚合中,但是我没有在成员聚合中保留广告列表(这样做需要使用流程管理器来避免在同一事务中更新2个聚合)。因此,我必须查询阅读模型,这正是我试图避免的。为什么你要通过阅读模型避免这么多阅读?也许我遗漏了什么。好吧,最终的一致性。。。我想,作为这门学科的新手,我的大部分研究(比如这里)表明,应该避免从写端(命令处理程序或流程管理器)访问读模型。我想有时候这条规则可能会被打破,如果这是其中的一次,我正在寻找验证。。。最明显的地方是在流程管理器中,通过一个服务来完成。最终的一致性是一个问题。但您可以在多个级别上进行评估:如果您的阅读模型生成附加到您的消息传递机制,并且您的消息传递机制保证了交付顺序,那么MemberWasBanked爆炸将在创建任何待定的新广告后发生,因此,不会出现最终的一致性问题。。。另一方面,如果您不能保证这一点,您可以通过某种排序清理过程(通过事件或不通过事件)保护自己以捕获掉队者。但您完全正确,需要做一些关于最终一致性的事情。或者您可以决定处理此一致性场景的麻烦太大,将广告列表保留在成员中,并在创建时与流程经理一起向这两个聚合写入内容。。。“我曾想过使用流程管理器,但读到您不应该从PM访问读取端”-您这样做不仅仅是出于弹性原因;否则PM需要基于事件构建私有状态,就像读取模型一样“在任何情况下,PM在大多数情况下决定发送给AR的命令。“-不,首相可以向许多人发送命令,谢谢你的评论-回复。在PM中建立状态,这是我仍然难以理解的一件事。在这种情况下,每个广告会有一个PM实例吗?如果您决定重播所有事件,如何恢复状态?似乎需要某种类型的存储库来重建它?然后呢。2-在这种情况下,从我的PM访问读取模型(通过服务)以读取属于用户的广告列表,然后对其发出挂起命令是否是有效的设计?re。2:如果您牺牲了PM的独立性,但减少了代码重复。这是你的选择我的PM被一个透明地忽略已经处理的事件的持久性所修饰。我的PM是用这层装饰的简单阅读模型