Unit of work vs. Transaction

Hi all,

I'm currently working on the Axon Auction Example and wonder what the
difference between a Unit Of Work and a Transaction in Axon really is.
Following Martin Fowler a Unit Of Work spans multiple requests
( http://martinfowler.com/eaaCatalog/unitOfWork.html ) but that isn't
the case with Axon as far as I can see - Or there was at least no
example for that :slight_smile:

Cheers,
Michael

Hi Michael,

the Unit Of Work was originally introduces to enable a single command to execute logic on more than one aggregate. If the aggregate is the transactional scope (which according to CQRS, it is), then we’re actually talking about more than one request here.

Currently, in Axon, the Unit Of Work has a more central role in managing the work done by command handlers. The Unit Of Work currently keeps track of the aggregates that have been loaded by the repositories and persists them when the UnitOfWork is committed. According to Martin, that’s exactly what a UoW should do, if I understand correctly.

Martin Fowler: "When you’re pulling data in and out of a database, it’s important to keep track of what you’ve changed; otherwise, that data won’t be written back into the database. Similarly you have to insert new objects you create and remove any objects you delete. […] A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you’re done, it figures out everything that needs to be done to alter the database as a result of your work. "

In Axon, when I talk about a transaction, I mostly mean an underlying database transaction in which changes are done to the database. However, that is completely optional. For example, a Unit could use an underlying database transaction when it is trying to write all its updates to the database.

That this answer your question?

Cheers,

Allard

Yeah, tnx.

Funny thing is that I yesterday watched this presentation video from
Greg Young (" 7 reasons why most DDD projects fail"):
http://vimeo.com/13824218

In this video he states that using a Unit Of Work is a sign that the
modeling of the Aggregate Roots is wrong. Calling
"repository.save(..)" should be the only transaction boundary.

Hi Michael,

and I fully agree with him. You should never do anything one more than one aggregate at a time.

But there are more motivations for the UnitOfWork in Axon.

I don’t like this approach:
aggregate = repository.load(…);
aggregate.doSomething();
repository.save(aggregate);

for several reasons. First: of course I want to save! I am not making these changes for kicks. Second: it provides some implementation details in the repository interface. We need to tell it so persist our changes. Third: it’s the same code, over and over.

In my command handlers, I have extracted the repository.load(id) into a separate method, called onMyAggregate(id).

This allows me to express what I want in more natural wording:

void handleMyCommand(DoSomethingCommand cmd) {
onMyAggregate(cmd.getIdentifier()).doSomething();
}

I agree, the UnitOfWork does allow users to break the one-aggregate-at-a-time rule. But I don’t want Axon to enfore CQRS rules, just to make it easier to build applications that conform to them.

Cheers,

Allard