Affects: \
Spring webflux does not support @TransactionalEventListener to publish event after transaction completed. So what i need to do to publish event only when transaction completed in Spring webflux?
Comment From: jhoeller
As of 6.1, @TransactionalEventListener
can work with thread-bound transactions managed by PlatformTransactionManager
as well as reactive transactions managed by ReactiveTransactionManager
. For the former, as of #30244, listeners are guaranteed to see the current thread-bound transaction. Since the latter uses the Reactor context instead of thread-local variables, the transaction context needs to be included in the published event instance as the event source, e.g.:
TransactionContextManager.currentContext()
.map(source -> new PayloadApplicationEvent<>(source, "myPayload"))
.doOnSuccess(this.eventPublisher::publishEvent)
Or via the new TransactionalEventPublisher
delegate:
new TransactionalEventPublisher(this.eventPublisher).publishEvent(source -> new PayloadApplicationEvent<>(source, "myPayload"))
new TransactionalEventPublisher(this.eventPublisher).publishEvent("myPayload")
Comment From: koenpunt
It's also possible to use the TransactionSynchronizationManager
to perform some code when a transaction finishes.
For example in kotlin:
@Transactional
suspend fun performSomething() {
userRepository.register()
val manager = TransactionSynchronizationManager.forCurrentTransaction().awaitSingle()
manager.registerSynchronization(object : TransactionSynchronization {
override fun afterCommit(): Mono<Void> = mono {
sendEmail()
}
})
}
Or similar in Java:
@Transactional
public void performSomething() {
userRepository.register();
TransactionSynchronization transactionSynchronization =
TransactionSynchronizationManager.forCurrentTransaction();
if (transactionSynchronization != null) {
transactionSynchronization.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
sendEmail();
}
});
}
}