【问题标题】:DDD: Can I modify two aggregates in a single transaction?DDD:我可以在一个事务中修改两个聚合吗?
【发布时间】:2021-11-30 12:35:27
【问题描述】:

所以我正在努力建立一个相当简单且非常普遍的关系。 我有一个包含很多实体的复杂应用程序,我想为一个用例建模,对于这个 UC,我有 3 个实体,组织、用户和邀请。这是业务规则/约束:

  • 一个用户可以属于一个或多个组织。
  • 组织可以向电子邮件发送邀请,该电子邮件可以是现有用户或新用户。 (这意味着创建邀请数据库实体)
  • 组织可以删除(更新状态:已删除)邀请(如果尚未接受)。 (这意味着更新邀请数据库实体)
  • 用户可以接受邀请(这意味着更新邀请和用户)
  • 用户可以拒绝邀请(这意味着更新邀请)

所以在这种情况下,用户是一个聚合根,我认为组织是另一个聚合根(还有其他与组织相关的实体),现在我不太明白邀请是什么,我倾向于聚合root 也是如此,但问题是,如果是这种情况,在接受邀请时,我需要在同一事务中修改邀请和用户,我认为这是我们想要避免的。 有什么想法吗?

【问题讨论】:

    标签: aggregate domain-driven-design


    【解决方案1】:

    我可以在一个事务中修改两个聚合吗?

    是的,您可以...如果您愿意接受所涉及的权衡(限制您选择持久存储、增加解决冲突的需求等)。

    但是:将聚合合并到单个事务中的压力通常是 (a) 未能认识到模型应该支持中间/非平衡状态或 (b) 意外的症状设计不正确的领域实体形式的复杂性。

    有什么想法吗?

    考虑是否可以通过对邀请过程建模而不是尝试对名词建模来满足您的要求。考虑是否最好通过指向可变数据引用的链接或制作所需数据的不可变副本来为您的模型提供最佳服务。

    【讨论】:

    • 感谢您的回答,无论您的评论从理论上讲是否有意义,我不知道如何从实现的角度解决这个简单的场景,我显然不完全了解 DDD,关于你的第二条评论,那会怎么样?你能发一个例子吗?
    • 在提议的突变中,只有一个需要突变两个聚合:用户接受邀请。为此,您可以在将邀请标记为已接受和通过发出域事件声明“此用户接受此邀请”来更新用户之间建立异步边界。后台进程可以获取接受,然后对用户进行更新。这确实会引入一段 [希望是短暂的] 不一致时期(从邀请的角度来看,用户接受了邀请,但用户聚合尚未反映这一点)。
    • 另一种方法是将邀请接受显式建模为具有状态的过程:接受过程尝试将邀请标记为已接受;尝试后,如果邀请显示为已接受,则更新用户,然后报告成功。再一次,这将导致一段不一致的时期;不同之处在于,这里的接受操作在两者都更新后被认为是成功的,而后台异步处理方法会在邀请更新并发出域事件后认为接受操作成功。
    • “前台进程”方法确实会产生一些复杂性,因为您需要一些方法来重新启动挂起的接受进程。
    • 所以我毕竟不是那么遥远,非常感谢您的澄清。
    猜你喜欢
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2010-09-06
    • 2018-09-13
    • 1970-01-01
    相关资源
    最近更新 更多