I have some method which is publishing an application event (MyEvent) and then I am logging "done publishing". The problem I am having is log statement is executed first and then MyEvent listener is getting invoked. How do i make sure execution order is like following:-
publish event
listen event
executing log statement [see code below]
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void method() {
//save something in db
applicationEventPublisher.publishEvent(new MyEvent(...params));
log.info("done publishing");
});
}
@TransactionalEventListener
@Order(2)
public void handle(MyEvent myEvent) {
//do something
}
The @TransactionalEventListener
is an event listener that is bound to the current transaction. It will execute the event at the given phase, the default is AFTER_COMMIT
.
So in your case the event will be executed after the execution of method()
. So the event will be fired, but not yet executed by the said listener. Hence the behaviour you see.
The event is in fact, by default, already delivered synchronously and not a-synchronously (which you expect due to the behaviour you see).
If you want to execute the event directly use a regular @EventListener
instead of an @TransactionalEventListener
.
@EventListener
@Order(2)
public void handle(MyEvent myEvent) {
//do something
}
Now the code will behave as you expect and want.