Issue
I have 3 event listeners listening on the same event:
- Save in DB
- Cache
- Publish message
Where 1
and 2
execute synchronously in order and 3
independently and asynchronously. I have enabled @EnableAsync
.
@Order(1)
@EventListener
fun handle(update: String) {
logger.info("Database $update")
//throw IOException()
}
@Order(2)
@EventListener
fun handle(update: String) {
logger.info("Cache $update")
}
@Async
@EventListener
fun handle(update: String) {
logger.info("Kafka $update")
}
Works as expected:
[nio-8080-exec-4] controller.Listener2 : Database user22
[nio-8080-exec-4] controller.Listener1 : Cache user22
[ task-21] controller.Listener3 : Kafka user22
Problem arises when Database handler fails:
[nio-8080-exec-7] controller.Listener2 : Database user22
[nio-8080-exec-7] controller.Controller : Failed to invoke event listener
Why wouldn't the asynchronous event listener get executed?
Solution
You can think about it as if the event dispatcher does not know anything about the @Async
annotation.
So the dispatcher calls the three methods in your designated order (or, as here, if you didn’t add an order, then in the default order) synchronously.
Only then, upon calling the proxied async method, the async proxy starts the original method in another thread.
The async proxy and the event dispatcher operate independently and don’t know about each other.
Answered By - jhyot
Answer Checked By - Candace Johnson (JavaFixing Volunteer)