简体   繁体   English

在域驱动设计中,事务是否可以修改多个聚合?

[英]In Domain Driven Design, may a transaction modify more than one aggregate?

In "Domain Driven Design: Tackling Complexity in the Heart of Software", Evans defines 在“领域驱动设计:解决软件核心中的复杂性”中,Evans定义

An Aggregate is a cluster of associated objects that we treat as a unit for the purpose of data changes. 聚合是一组关联对象,我们将其视为数据更改的单位。

Obviously this implies that an aggregate must be updated in a single transaction. 显然,这意味着必须在单个事务中更新聚合。

However, must a transaction only update a single aggregate? 但是,事务必须只更新单个聚合吗? If so, why? 如果是这样,为什么?

My Research 我的研究

I ask because, in "Implementing Domain Driven Design", page 360, Vernon writes: 我问,因为在第360页的“实施领域驱动设计”中,弗农写道:

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. 在单个事务中只能修改一个或另一个。

but does not give a reason for this rule. 但没有给出这条规则的理由。

I understand that if business rules require a single transaction, this indicates a hidden invariant, which would require the entities to be part of the same aggregate. 我理解,如果业务规则需要单个事务,则表示隐藏的不变量,这将要求实体成为同一聚合的一部分。 But what if the business does not care, and developers simply find it convenient? 但如果业务不关心,开发人员只是觉得方便呢?

On page 437, Vernon also writes: 在页437,弗农还写道:

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. 如果你不小心,那么在开发和测试中运行良好的东西会因为并发问题而在生产中严重失败。

Which concurrency issues are those? 哪些并发问题是那些?

Optimistic concurrency is often used to avoid data losses in an environment where contention exists. 乐观并发通常用于避免存在争用的环境中的数据丢失。

Let's see what would cause a concurrency exception with that mechanism in place: 让我们看看是什么会导致该机制的并发异常:

  1. User Foo load aggregate A which is of version V1. 用户Foo加载版本为V1的聚合A.
  2. User Bar load aggregate A which is of version V1. 用户栏加载聚合A,版本为V1。
  3. User Foo changes the aggregate A and persists (version is incremented to V2). 用户Foo更改聚合A并保持不变(版本增加到V2)。
  4. User Bar changes the aggregate A and tries to persist but will get a concurrency exception because his changes were based on V1, but the aggregate is now at V2. 用户栏更改聚合A并尝试保持但会获得并发异常,因为他的更改基于V1,但聚合现在为V2。

If you allow modifying more than a single aggregate per transaction, you are increasing the risk of concurrency exceptions, which might harm the scalability of your system up to the point of making it unusable. 如果允许每个事务修改多个聚合,则会增加并发异常的风险,这可能会损害系统的可伸缩性,直至使其无法使用。

Aggregate roots (AR) are transactionnal boundaries , where invariants are transactionnaly consistent , so if you find yourself trying to modifying multiple ARs in the same transaction it means that your AR boundaries are probably wrong and that you might be missing the chance of making an implicit concept explicit. 聚合根(AR)是事务边界 ,其中不变量是事务一致的 ,因此如果您发现自己试图在同一事务中修改多个AR,则意味着您的AR边界可能是错误的,并且您可能错过了隐含的可能性概念明确。

However, note that there should be no problem in creating multiple ARs in a single transaction. 但请注意,在单个事务中创建多个AR应该没有问题。

Common mistakes when designing ARs are to create large clusters by giving too much importance to the relation words in statements like: 设计AR时常见的错误是通过过分重视语句中的关系词来创建大型集群:

"Posts have comments" “帖子评论”

There's no reason to cluster Post and Comment together if there's no invariant enforcement which requires that composition. 如果不存在需要该组合的不变执行,则没有理由将PostComment聚合在一起。 Should two authors posting on the same comment at the same time cause a concurrency exception? 两个作者是否应该同时在同一个评论上发布会导致并发异常? The answer is probably no, depending on your domain, but it would if Post contained a collection of Comment . 答案可能是否定的,具体取决于您的域名,但如果Post包含Comment集合,则会有答案。

But what if the business does not care, and developers simply find it convenient? 但如果业务不关心,开发人员只是觉得方便呢?

Well, if the business do not care about their system being unscalable due to bad design decisions I guess that's their choice, but developers shouldn't make a habit of designing for convenience. 好吧,如果企业不关心他们的系统由于糟糕的设计决策而不可扩展,我想这是他们的选择,但开发人员不应该养成为方便而设计的习惯。 DDD is about modeling the domain the way it is, not the way it is convenient to model. DDD是关于对域进行建模的方式,而不是建模方便的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM