java - 在领域驱动设计中,一个事务可以修改多个聚合吗?

标签 java transactions domain-driven-design aggregateroot

在“领域驱动设计:解决软件核心的复杂性”中,Evans 定义

An Aggregate is a cluster of associated objects that we treat as a unit for the purpose of data changes.

显然,这意味着聚合必须在单个事务中更新。

但是,一个事务必须只更新一个聚合吗?如果是,为什么?

我的研究

我问是因为,在“实现领域驱动设计”,第 360 页,Vernon 写道:

Both the referencing aggregate and the referenced aggregate must not be modified in the same transaction. Only one or the other may be modified in a single transaction.

但没有给出这条规则的原因。

我理解,如果业务规则需要单个事务,这表明存在隐藏的不变量,这将要求实体成为同一聚合的一部分。但是,如果业务不关心,而开发人员只是觉得方便怎么办?

在第 437 页,Vernon 还写道:

Be careful not to overuse the ability to commit modifications to multiple aggregates in a single transaction just because it works in a unit test environment. If you aren't careful, what works well in development and test can fail severely in production because of concurrency issues.

哪些并发问题?

最佳答案

乐观并发通常用于避免存在竞争的环境中的数据丢失。

让我们看看在适当的机制下什么会导致并发异常:

  1. 用户 Foo 加载版本 V1 的聚合 A。
  2. 用户 Bar 负载聚合 A,版本为 V1。
  3. 用户 Foo 更改聚合 A 并保留(版本为 增加到 V2)。
  4. 用户 Bar 更改聚合 A 并尝试坚持但会得到 并发异常,因为他的更改是基于 V1,但是 聚合现在处于 V2。

如果您允许在每个事务中修改多个聚合,则会增加并发异常的风险,这可能会损害系统的可扩展性,直至无法使用。

聚合根 (AR) 是事务边界,其中不变量是事务一致的,因此如果您发现自己试图修改多个 AR同样的交易,这意味着您的 AR 边界可能是错误的,并且您可能错过了将隐含概念明确化的机会。

但是请注意,在单个事务中创建多个 AR 应该没有问题。

设计 AR 时的常见错误是通过过于重视语句中的关系词来创建大型集群,例如:

"Posts have comments"

如果没有需要这种组合的不变强制,则没有理由将 PostComment 聚集在一起。两位作者同时发表同一条评论是否会导致并发异常?答案可能是否定的,具体取决于您的域,但如果 Post 包含 Comment 的集合,则答案是肯定的。

But what if the business does not care, and developers simply find it convenient?

好吧,如果企业不关心他们的系统由于糟糕的设计决策而无法扩展,我想这是他们的选择,但开发人员不应该养成为了方便而设计的习惯。 DDD 是按照领域的本来面目对领域进行建模,而不是方便建模的方式。

关于java - 在领域驱动设计中,一个事务可以修改多个聚合吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28222444/

相关文章:

java - 领域驱动设计实用程序类并通过实体中的存储库

java - 浏览器在后退按钮上注销

Java 反序列化数组列表时所有值为 null

sql - SERIALIZABLE 隔离级别上的两个并发事务

domain-driven-design - 是否可以根据服务拥有一个存储库?

python - 使用 DDD 方法在 Python 中保留 POJO

java - 没有连接适配器;跳过布局 onCreateView()

java - 如何执行检查类型转换?

sql - 事务会阻止其他代码读取不一致的数据吗?

mysql - 没有锁的事务中读-过滤-写可能出现哪些失败模式?