Small Aggregates Vs. Big Aggregates

For most of the websites and projects where we've worked, almost 95 percent of Aggregates were formed by one single root Entity and some Value Objects. No other Entities were required to be in the same Aggregate. So in most cases, there was no real true business invariant to keep consistent.

Be careful with the has-a/has-many relations that don't necessarily make two Entities become one Aggregate, with one of those being the root. Relations, as we will see, can be handled by referencing Entity Identities.

As explained in the introduction, an Aggregate is a transactional boundary. The smaller the boundary is, the fewer chances there are for conflicts when committing multiple concurrent transactions. When designing Aggregates, you should strive to create them small. If there's no true invariant to protect, that means all single Entities form an Aggregate by themselves. That's great, because it's the best scenario for achieving the best performance. Why? Because locking issues and failed transaction issues are minimized.

If you decide to go for big Aggregates, keeping data consistent can be easier but is probably impractical. When applications with big Aggregates run in production, they start to experience issues when multiple users perform operations. When using optimistic concurrency, the main problem is transactional failures. When using locking, the problem is slowness and timeouts.

Let's consider some radical examples. When using optimistic concurrency, imagine that the whole Domain is versioned, and each operation on any Entity creates a new version for the whole Domain. With this scenario, if two users were performing different operations on different Entities that couldn't be related at all, the second request would experience a transaction failure because of a different version. On the other hand, when using pessimistic concurrency, imagine a scenario where we lock the database on each operation. That would block all the users until the lock is released. This means many requests would be waiting, and at some point, probably timed out. Both of these examples keep data consistent, but the application can't be used by more than one user.

Last but not least, when designing big Aggregates, because they may hold collections of Entities, it's important to consider the performance implications of loading such collections in memory. Even using an ORM such as Doctrine, which can lazy load collections (load collections only when they are needed), if a collection is too big, it can't fit into memory.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.160.43