Microservices 如果Post和Comment是单独的聚合根,如何尊重Post.CommentsAllowed?

Microservices 如果Post和Comment是单独的聚合根,如何尊重Post.CommentsAllowed?,microservices,domain-driven-design,Microservices,Domain Driven Design,在2个聚合根的经典示例中,如下所示: class Post { string AuthorId; string Title; string Content; boolean AllowComments; ... } class Comment { string AuthorId; string Content; DateTime Date; ... } 创建新评论时,如何确保只将评论添加到具有post.AllowComments=true的帖子 请记住,当

在2个聚合根的经典示例中,如下所示:

class Post
{
  string AuthorId;
  string Title;
  string Content;
  boolean AllowComments;
  ...
}

class Comment
{
  string AuthorId;
  string Content;
  DateTime Date;
  ...
}
创建新评论时,如何确保只将评论添加到具有
post.AllowComments=true
的帖子

请记住,当用户开始写评论时,
Post.AllowComments
很可能是
true
,但同时(在写评论时),
Post
作者可能会将其更改为
false
。 或者,即使在提交时=>当我们选中
Post.AreCommentsAllowed()
时,它也可能返回
true
,但当我们选择
CommentRepository.Save(comment)
时,它可能是
false

当然,一篇
Post
可能有许多
注释
,因此在
Post
包含
注释的集合的地方使用单个聚合可能不太实际

还有其他解决办法吗

附言。 我可以在db事务中检查它,但我正在寻找一个DDD纯粹的解决方案

我正在寻找一个DDD纯粹的解决方案

首先,基本思想是:如果我们的评论逻辑需要来自Post聚合的信息,那么我们通常要做的就是将该信息的副本作为参数传递

因此,在本例中,我们的应用程序代码将获取AllowComments的本地副本,可能是通过检索Post-aggregate根的句柄并在其接口中调用一些查询来实现的

在注释聚合中,您可以根据需要使用该信息(例如,作为某些分支逻辑的参数)


比赛条件艰苦

时间上的微秒差异不应该对核心业务行为产生影响

如果这里的数据必须与那里的数据一致,那么答案是我们在进行更改时必须同时锁定这两个数据

在一个信息存储在本地的应用程序中,这很简单,至少在纸面上是这样:您只需要同时获取两个对象上的锁,这样数据就不会从您的下方更改出来。有一点需要小心,以确保你陷入僵局(又名餐饮哲学家问题)

在分布式系统中,这会变得非常糟糕

“现代纯粹主义DDD”中的常见答案是,您要么放宽一致性要求(允许您在工作时更改正在读取的锁),要么缓解其他地方的不一致性(见Pat Helland),要么更改聚合设计,以便将所有信息都包含在同一个聚合中(这里,这意味着让评论实体成为帖子聚合的一部分)


另外:创建模式很奇怪;您希望您要创建的实体在存储库中还不存在(但可能不存在),因此业务逻辑不能像通常的“从存储库获取句柄”模式那样顺利地适应

因此,条件逻辑需要潜入其他地方——可能进入后期聚合?可能您只是将其留在应用程序代码中?最终,如果存储库中保存了任何内容,则必须有人告诉应用程序代码


据我所知,关于如何在DDD中处理条件创建逻辑,目前还没有达成广泛的共识,只是有很多不同的折衷方案,在它们的本地环境中可能“足够好”。

请您澄清一下“您希望您要创建的实体在存储库中还不存在”是什么意思(但可能会偏离愉快的路径),因此业务逻辑不能像通常的“从存储库获取句柄”模式那样顺利地适应?