Nested commands?

154 views
Skip to first unread message

stanleysf

unread,
Feb 27, 2011, 4:46:46 PM2/27/11
to Axon Framework Users
AxonFramework looks great for a 1.0 product. I am evaluating axon
framework for use in our new SAAS product and there are some concerns.

1) Are there plans to have a better way for nesting commands? Right
now each command creates new UnitOfWork without any regard for a
"current unit of work". We want ACID transactions on the single
database via composition of commands.

Consider this case: We have a CreateUserCommand that creates a user
with 'normal' permissions, and a "ModifyUserRoles" command that adds
specific roles to a user. I would like to have a
"CreateManagementUser" command that invokes both of the other commands
within a single database transaction (single UnitOfWork). It appears
I have to wire this up inside the domain objects to get proper event
handling. There are other more examples where the complex command
may involve several subcommands, all of which are one logical
transaction for the database and UI.

2) We need to use the "hybrid" model where the domain objects write
directly the database, without event sourcing. It is a requirement
that we return "success" in the UI only when the database commit
succeeds. There is not quite enough documentation yet on this,
particuarly about how the transaction management is handled. It
appears the addressbook example is such an application but this is not
made clear.


Allard Buijze

unread,
Feb 28, 2011, 3:04:24 AM2/28/11
to axonfr...@googlegroups.com
Hi,

1) The UnitOfWork is nesting aware. That means it is possible to create a single transaction that deals with commands that cause other commands (via events, usually).

However, it is usually a design flaw if your application really relies in this. In your example, why do you send 2 commands to create a user? Why not send a single command that does the whole job at once? I haven't encountered a single case (yet) where it really wasn't possible to capture an atomic action in a single command (and acting on a single aggregate).

2) You can use the GenericJpaRepository to store your aggregates using JPA (the AbstractAggregateRoot is JPA-annotated). If you want something else, you can easilly create a subclass of the LockingRepository or AbstractRepository. These abstract repositories deal with the UnitOfWork handling for you.

To add transactional behavior to your commands, you can configure an Interceptor. If you use Spring, you can use the SpringTransactionalInterceptor to start a transaction using the PlatformTransactionManager in your spring context. This interceptor will check the UnitOfWork for a success or failure. If you need another type of transaction, you can extend the abstract TransactionInterceptor class. It will allow you to commit the transaction when the UoW is committed, and rolled back when the UoW is rolled back.

I hope this clarifies stuff a bit. If you have any concerns, don't hesitate to let me know.

Cheers,

Allard
Reply all
Reply to author
Forward
0 new messages