One of the requirements of the aggregate pattern is that the aggregate has a root and a boundary and that the aggregate as a whole is the unit that we consider when looking at concurrency.
This has bothered me for a while as NHibernates concurrency is based on a version column at the row level, which is a completely different way of doing things.
For example if a Customer has a CustomerIdentification and both are in one row then we're OK, modifying either and saving the Customer will cause NHibernate to check that the row hasn't changed since we loaded it.
But lets say that the CustomerIdentification is in it's own table, now if we modify the CustomerIdentification and save then the save will pass even if someone else has modified the Customer. That can cause problems (see Eric Evans' book on DDD for concrete examples of the issues it can cause).
I looked it up in Nilssons "Applying Domain-Driven Design and Patterns" and was in luck as page 127 had the following:
"...an Order including its OrderLines is a concurrency conflict detection unit of it's own or - more conceptually - an Aggregate...".
He then goes on say that because the aggregate is the unit as far as concurrency we don't need to worry about other users interfering. Exactly what we need. I have read the book before so I was surprised that if it had a solution to this I'd missed it so I looked on, page 309 indicates two things:
- We want to use coarse-grained locks at the aggregate root level.
- We want to use a version field on the aggregate roots
The second bit confused me but its only for optimistic offline locking (though I would have thought you'd use that for all objects or for none). It doesn't seem to get me any closer to actually getting coarse grained locking working though so I skipped to page 341 covers how NHibernate works with concurrency and it tells me that NHibernate doesn't give us coarse grained locking. And thats all, no more reference to how we can get this important capability, even though the earlier examples assumed that we had a way of doing it. Back on the shelf for you.
Having said that I was particularly interested in the discussion of coarse grained locking of aggregates in Fowlers excellent "Patterns Of Enterprise Application Architecture". On page 439 the idea of a "root lock" is introduced, the root of the aggregate would have a lock and all parts of the aggregate would use it.
The book points out that for this to work we need to be able to navigate from any part of the aggregate back to the root, indirectly (with each one having a reference to its "parent") or directly (each has a reference to the root).
For me for now this is too much, having to couple each part of the aggregate directly to the root is too much and even coupling each part to the parent is troublesome, not least as to ensure that relationship is maintained when reloaded from persistence I'm going to need to store the relationship in the database. Unless I'm missing something obvious, which is quite possible.
For now I'll forget it :)