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