Are Multi-Command Transactions Possible?

Hi Allard,

First off I want to say thanks for all the work you’ve done on the framework. The Reference Guide is not only extremely helpful for learning Axon, but it has been the single most helpful CQRS/ES resource I have come across. Great work.

I’m currently leading an initiative on my team to evaluate Axon for use in a new product. One of our high level plans up to this point was to execute multiple Commands within a single transaction, but after reading the “Binding the Unit of Work to a Transaction” section of the Reference Guide (under 3.4), it’s seems like that may not be an option within Axon, or even the right way to go about things.

I can’t go into too much detail about our business problem, but here are the reasons why we were planning on multiple Commands per transaction:

  • Our system is downstream from our external client system(s).
  • We receive unbounded streams of semi-structured text-based messages from the external client systems which are snapshots of data from their system, and we need to use this information to construct our application’s state.
  • Each of these data-snapshot messages contains some subset of state from the client system which applies to potentially multiple aggregates within our system
  • Therefore, our plan is to transform each message into multiple commands in our domain, but keep the transactional boundary aligned with the message supplied by the external system.
  • The fact that we are receiving snapshots coupled with the lax and non-discrete nature of the messaging standard we are dealing with makes it hard to discern intent of the external system (i.e. what operation actually happened and what has changed), and this message to command transformation is where the real “dirty work” is intended to happen, allowing us to keep our domain aggregates clean with well defined command interfaces.

You may be able to deduce our project’s domain from these clues, but I hope this makes some sense.

Even with the less than ideal circumstances above, the Command Pattern as implemented by Axon seems like a great fit, with CQRS/ES possibly also playing a key role.

Thanks for your help,


P. S. We may be interested in some consulting in the near future if that’s a possibility and we haven’t already hit a dead end with what we’re trying to do.

Hi Chris,

although it is not considered good practice to handle multiple commands in the same transaction, it is sometimes a more pragmatic solution. In Axon, it is possible to do so. If you use the SpringTransactionManager, the Unit of Work will automatically be bound to the transaction if one already exists. That transaction will then not be committed at completion of the Unit of Work.

Hope this helps.
Kind regards,

Allard Buijze

Yes this definitely helps. Thanks.

Hi Allard,
We also need to handle multiple commands in the same transaction and I am new to axon, would you please give me more details about how to do it?
For now, I use the SpringTransactionManager, which wraps the JpaTransactionManager, however a new transaction is created for every command. How can I explicitly start a transaction and share it among multiple specific set of commands?
Thanks in advance.
Best regards,


One thing you can do is create a batch command. This command simply dispatches the commands that it contains. This will cause Axon to create a transaction for the batch command. If the individual commands are handled in the same thread, they will automatically attach to the already running transaction, instead of creating their own.

I can’t stress enough that this is really bad design, though. You’re tying yourself to using the SimpleCommandBus. As soon as you start using another implementation, these guarantees are lost. It’s best to stick to 1 command = 1 transaction.



Hi All,

nice discussion that made me think of what I did in this case.
Allard is a DDD/CQRS master and it is always best to follow his valuable advice but there is probably an exception which allows a command batch to work in a distributed context as long you are respecting the routing policy.
Supposing to use the Aggregate Id as the routing key it should be possible to send a batch of commands provided that all commands share the same routing key.

You can find an example below:


Hi all,
thanks a lot for the quick response and great advices, it helps.