views:

33

answers:

1

Let's take an example UI for editing Customer information. The user edits 5 fields and presses "submit". Because we're good abstractionists, we've taken the edits to the 5 fields and make them different commands (describing the edit to a particular field).

The command handlers end up setting properties on objects that are persisted with a tool such as NHibernate, so we end up with doing an UPDATE against the database.

My main question is: from a database performance point-of-view, does it make more sense to issue a single UPDATE statement or is it okay to issue 5 different UPDATE statements?

I like the idea of a command handler being a transactional boundary. Either it works and the transaction is committed, or it doesn't and the transaction is rolled back (and we possibly re-queue to try again). The success or failure of each command is independent from the other.

The other approach might be to wrap the handling of these commands into a single database transaction, so that when NHibernate decides to flush it ends up sending a single UPDATE. But this makes the handling of the commands an all-or-nothing type deal, and I can't necessarily execute them asynchronously.

But if I wanted to make sure all of the commands executed properly, and rollback entirely in the case of failure? Maybe there is a single distributed transaction containing many smaller transactions? This could lead to database contention, increasing the risk of deadlocks, which slows down processing (further increasing the risk of deadlocks). But at the same time, consistency is key. I suppose it's a trade off between availability and consistency (see CAP).

+1  A: 

From a database perspective it is almost always better to issue a single update - but it depends on the context whether it really matters or not.

However, I'm not sure that as 'a good abstractionist' you'd really want to issue 5 commands when 5 fields get edited. What you really want to do in DDD is issue a single command for each logical operation that a user is doing through the UI. Usually this is just one per operation, although it could be more than one for more complex scenarios. To take a trivial example, if someone is updating their address you don't have one command for each field - you have a command for updating an address.

The lowest level of granularity that you have will be a command, so whatever is in the command handler needs to be wrapped in a transaction. What we do is put commands into a unit of work so when we issue more than one command they either all pass or all fail. At the end we commit the transaction, meaning any changed objects (for us it's the aggregate root plus events as we're using event sourcing) get persisted. If you're using NHibernate to do this, it will potentially do it one operation - although of course that's down to what you're doing with persistance.

FinnNk
I believe you're right about the multiple commands; issue commands for a single logical operation such as "updating customers's phone number" or "updating customer's name" (might be multiple fields).But why wouldn't each command be the unit of work? This might make sense if, for example, these commands are being sent to some other process to execute asynchronously.We do execute commands wrapped in one transaction to benefit from NHibernate's management of how many SQL statements to execute. But since this is all-or-nothing, I feel it breaks the natural unit-of-work of a command.
Joseph Daigle