How should one handle compensating commands (or events)?

Hi all,

I have a situation where an event handler might dispatch a new (compensating) command for some events.

@EventHandler

public void handle(SomethingHappenedEvent event){

commandBus.dispatch(new CompensatingCommand());

}

Where the compensating command handling looks something like this

@CommandHandler

public void handle(CompensatingCommand command){

MyAggregate aggregate = repository.load(command.aggregateId());

try {

aggregate.compensateSomething();

} finally {

repository.save(aggregate);

}

}

And the original command handling was pretty much identical

@CommandHandler

public void handle(SomeCommand command){

MyAggregate aggregate = repository.load(command.aggregateId());

try {

aggregate.doSomething();

} finally {

repository.save(aggregate);

}

But this would cause and exception to be thrown from the repository (because the nested handler will have access to the lock and release it before the outer).

java.lang.IllegalStateException: No lock for this aggregate was ever obtained

at org.axonframework.util.Assert.state(Assert.java:40)

at org.axonframework.repository.PessimisticLockManager.releaseLock(PessimisticLockManager.java:83)

at org.axonframework.repository.LockingRepository.save(LockingRepository.java:118)

at org.axonframework.repository.LockingRepository.save(LockingRepository.java:48)

How should one tackle situations like this?
A simple workaround is to dispatch the CompensatingCommand from a new thread (which I often already do for other reasons) but that might not be suitable in all scenarios.

Regards,

Ola

Hi,

we’re having a very similar, if not the same problem here. I am actually planning to build a solution into Axon this weekend.

What it will do is the following: if a command is dispatched in a thread that is already processing another command, then the command is queued for processing. The thread continues to dispatch events. When command handling is finished, it will check the queue for more commands. The process repeats until all commands are processed.

Obviously, you will need to have a special type of command bus. That’s what I’ll try to get done this weekend.

The message of the lock never being obtained is weird. That’s probably a bug. Which version of Axon are you using?

Cheers,

Allard

Cool, keep up the good work!

I thought I was running against the latest version in trunk but apparently I was not.
After updating to revision 1135 the exception is gone so it is had already been fixed.

Regards,

Ola

2010/7/16 Allard Buijze <buijze@gmail.com>

Hi Ola,

issues 22 and 60 took all of my available time last weekend. I have created an issue (#64) for this one, and will pick it up soon.

Cheers,

Allard