register "trigger" handler

Hello,
In current implementation we have requirements that before/after some state changes (objectCreated|objectDeleted|…) we need to perform actions. e.g. publish commands and depending on their result -> continue current unit of work|rollback|send compensating command
I found that I can do this with UnitOfWork#onCommit #onPrepareCommit #afterCommit

I was doing this in command’s MessageHandlerInterceptor, but then I realised that I should preform actions based on events instead of commands (right?). So I’d like to move this functionality elsewhere.
when I can send compensating task, then it could be @EventHandler method, but when I want to rollback current unit of work (don’t allow to commit changes made by initiating command) where should I register the handler?

Or is there any “best practices” advice how to do this kind of operations?

Thanks

Lukas

Also is there way how to register some “trigger action” after unitOfWork has been started (#onUnitOfWorkStarted())?
Stupid scenario but we have it now :confused: (we are not using event sourcing for this ) when I want to delete my object I need to delete it dependencies from other entities which has foreign key on this table with restrictions.

Actually for situation above I will need something like #onBeforeStarted().
but when I debug the code inside MessageHandlerInterceptor (for command) the phase is already STARTED.
So even if I modify class AbstractUnitOfWork (add #onBeforeStarted(handler)) and modify method #start() to change phase I don’t know where to issue this handlers registration.

Hi Lukas,

I don’t understand why you would need to perform actions before a Unit of Work has started to implement this. Interceptors are invoked before any processing has started yet. So even though a Unit of Work has started, the handlers haven’t been invoked yet. You can probably perform your actions at that point.

If I understand correctly, you have a table where other tables point to using foreign keys. You want to delete an entry, while there are foreign keys pointing at it. To me, it sounds like either the foreign key is there for the wrong reason, or the delete should simply be preceded by a delete of the referencing items. I guess “regular” best practices apply here, nothing really CQRS related.

Hope this helps.
Allard

Hi Allard,

when UOF is in STARTED state does it mean that transaction (DB transaction) has been already started? If so, I’m out of luck with this, because I’ll always have reference items available in current transaction.

You understand the problem correctly and we are planning to remove that FK, but we are wondering if there isn’t other way besides removing ref items before main item.

Where are you handling such methods? In commandInterceptors|eventInterceptors|eventHandlers?

thanks

Hi Lukas,

if you remove both ends of a FK in the same transaction, it should accept that, as far as I know.
But anyway, if you place your interceptor before the one that manages the transaction, you can do things before the transaction is started.

I never come across these issues normally, as I avoid FK’s like the plague. Oh well, maybe not as bad, but I do need to be sure that they defend a real constraint, and aren’t just there because the data in two columns seems to refer to the same concept…

Cheers,

Allard

Yes I don’t like FK’s also.
Current situation is that we have ObjectTypeAggregate (which is in it’s basics database table definition) and ObjectAggregate which represents record in ObjectType. There are some relations between ObjectTypes (currently FK). So there is restriction for user’s to not be able to simply delete some records(Objects) of ObjectTypes.

To remove object I’m using DeleteObjectCommand. In interceptors I’m doing custom actions for specified ObjectTypes when handling this command.
So it’s not possible to remove FK’s in one transaction (yes it is but it’s ugly hack), instead I was thinking of doing some PRE transaction operation.
As this could be possible with AsynchronousCommandBus - as you suggested register interceptor before TransactionManagingInterceptor but how could I do that with SimpleCommandBus?

Also now I’m handling this on Command side…would it be possible to move this to Event side? e.g. using EventHandler or MessageInterceptor for EventMessage?

Hi Lukas,

in Axon 3, you can define MessageInterceptors on the Command Bus, or on Event Processors. So if you want to do something before an event is handled, you can define the interceptor there.

When calling registerInterceptor on the SimpleCommandBus, make sure you define the DeleteStuffInterceptor before the TransactionManagingInterceptor. That way, the DeleteStufInterceptor is invoked before a transaction is created. Some components allow you to configure a TransactionManager. It’s likely that this essentially creates an interceptor, which always comes first. So don’t configure a TransactionManager on your CommandBus, but do it via a TransationManagingInterceptor.

Cheers,

Allard