Robust event dispatching

Looking at the source code it appears that under certain failure scenarios events would be lost even though aggregate has been successfully persisted. The case in mind:

  1. A command is issued which modifies an AggregateRoot instance.
  2. The aggregate root captures the state changes and dispatches events.
  3. The underlying Repository registers its savecallback with UnitOfWork.
  4. The dispatched events are kept “in memory” by the UnitOfWork via the EventContainer callback.
  5. UnitOfWork is finally committed which does following things in order:
    a. It calls the repository via savecallback to persist the aggregate to the data store (which can be transactional)
    b. It dispatches all the messages on the event bus which the repository provided

Now, if the process were to crash right after 5a but before 5b then all those messages will be lost.
I don’t see any logic to re-dispatch those messages when the process comes back up.

Note that our plan is to use traditional JPA based single state RDBMS and NOT use the event sourcing persistence mechanism. But, maybe there is a way to replay messages by using HybridJPARepository (event store will have the messages)?

Axon is really cool framework and we are looking for suggestions about the right configuration/approach to achieve fault tolerance in this case as we can’t afford to loose business critical messages.

Regards,
Aditya

Hi Aditya,

the only way to make it secure, is by attaching a Transaction to the UnitOfWork, as described i. The reference guide (http://www.axonframework.org/docs/2.0/command-handling.html#unit-of-work).

Depending on how sure you need to be, you could use a 2pc transaction.

Cheers,

Allard

Hi Allard,

Thanks for the quick response. Is there a sample/example I can look at? And is the transaction support well tested and mature?

We plan to use Oracle RDBMS with JPA as data store and Weblogic JMS for messaging (i have written a simple axon-jms module for it). If you could provide a brief outline of the necessary steps that would be great.

Regards,
Aditya

Hi,

all you need to do is configure a transaction manager on the command bus. If you use spring, you can use Spring’s PlatformTransactionManager in the axon:command-bus/ element. Otherwise, you may need to implement the TransactionManager interface and delegate it to whatever transaction manager(s) you’d like to use.

Cheers,

Allard