In Domain Driven Design, may a transaction modify more than one aggregate?
Asked Answered
N

1

7

In "Domain Driven Design: Tackling Complexity in the Heart of Software", Evans defines

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:

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:

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?

Necrophilism answered 29/1, 2015 at 18:57 Comment(1)
I answered something similar: #23464023Unbelieving
K
7

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.
  2. User Bar load aggregate A which is of version V1.
  3. User Foo changes the aggregate A and persists (version is incremented to 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.

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.

However, note that there should be no problem in creating multiple ARs in a single transaction.

Common mistakes when designing ARs are to create large clusters by giving too much importance to the relation words in statements like:

"Posts have comments"

There's no reason to cluster Post and Comment together if there's no invariant enforcement which requires that composition. 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.

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.

Keverne answered 30/1, 2015 at 3:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.