micronaut-data
micronaut-data copied to clipboard
TransactionalEventListener fails over upgrade Micronaut-data
Expected Behavior
In our codebase we use the micronaut TransactionalEventListener to perform logic just before completion of a transaction. Expected this code to work after upgrading.
Actual Behaviour
That code stopped working after an upgrade of micronaut, specifically micronaut-data. (from 4.3.0 to anything higher)
Steps To Reproduce
Reproduced in separate module with just 2 beans:
@Singleton
public class TxLead {
@Inject
private ApplicationEventPublisher<String> eventPublisher;
@Transactional
public void lead() throws SQLException {
System.out.println("Before publish");
eventPublisher.publishEvent("something");
System.out.println("After publish");
}
}
and
@Singleton
public class TxFollow {
@TransactionalEventListener(TransactionalEventListener.TransactionPhase.BEFORE_COMMIT)
public void becauseOfEvent(final String event) {
System.out.println("Listener to event " + event);
}
}
This setup works correctly with the following versions: <micronaut.version>4.3.3</micronaut.version> <micronaut.data.version>4.3.0</micronaut.data.version>
After upgrading micronaut data to 4.3.1 (or any newer up to 462) the listener does not act/print anymore.
Environment Information
- On Windows 11
- openjdk 17.0.9
Example Application
No response
Version
4.3.3
I have faced to the similar problem working with Micronaut (4.3.7) with Data R2DBC and Kotlin. I my code
@Singleton
open class BookLoggingListener {
@TransactionalEventListener
open fun onCreated(event: BookCreated) {
...
}
}
Every time I see this message:
16:38:50.521 [reactor-tcp-nio-1] DEBUG i.m.t.a.TransactionalEventListener - No active transaction, skipping event ...
After some investigation I have found some weird thing...
In TransactionalEventInterceptor
there is such a code:
@Singleton
@Internal
public class TransactionalEventInterceptor implements MethodInterceptor<Object, Object> {
...
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
...
transactionEventInvocation.transactionManager
.findTransactionStatus()
.ifPresentOrElse(transactionStatus -> {
...
...
}
If you go to the implementation of the .findTransactionStatus()
it will lead you to the SynchronousTransactionOperationsFromReactiveTransactionOperations
class.
And in this class you'll see this:
@Internal
public final class SynchronousTransactionOperationsFromReactiveTransactionOperations<T> implements TransactionOperations<T> {
...
@Override
public Optional<? extends TransactionStatus<?>> findTransactionStatus() {
return Optional.empty();
}
...
}
So this feature appears to be disabled... 😄
@temofey1989 This feature is not supported for the reactive transactions
@bweefting Are you using reactive TX manger? Can you please create a sample app?
@dstepanov Thanks for the quick feedback. Can I ask you if you have a plan to support this feature in future for Reactive Transactions? Maybe this question also related to #2826. Thanks.
Not sure it can be possible. You can get ReactiveConnectionStatus
you can add a callback yourself.
@temofey1989 This feature is not supported for the reactive transactions
@dstepanov Could this be perhaps documented in the annotation's javadoc please? Just spent some time on this problem until I found this ticket/comment. Maybe I missed this in docs/guides, I am not sure.
Thanks.
@temofey1989 This feature is not supported for the reactive transactions
@dstepanov Could this be perhaps documented in the annotation's javadoc please? Just spent some time on this problem until I found this ticket/comment. Maybe I missed this in docs/guides, I am not sure.
Thanks.
@wetted please, documenta that Transactional Events are not supported for reactive transactions