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?
Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. An example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate.
Aggregates. The stategic DDD's bounded contexts typically contain multiple aggregates. Within the aggregates, you can model your system with the tactic DDD patterns, such as Entity, Value Object, Domain Event, Service and Repository. The page Aggregate describes how you can create aggregates.
Put another way, a Bounded Context encompasses one or more Aggregates.
Advantages of domain-driven design The most obvious advantage of DDD is that it gets everybody using the same language. When development teams use the same language as domain experts, it leads to software design that makes sense to the end user.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With