Given a transactional, reactive service:
@Service
static public class S {
@Transactional
public Flux<String> something() {
return Flux.just("foobar");
}
}
and two transaction managers in the context, one being an instance of AbstractPlatformTransactionManager and one AbstractReactiveTransactionManager, the service should use the reactive transaction manager as indicated by the return type.
However, the TransactionAspectSupport fails to determine the correct one to use.
In determineTransactionManager it ultimately asks the beanFactory for an instance of TransactionManager, which fails with a org.springframework.beans.factory.NoUniqueBeanDefinitionException.
A workaround would be specifying which tx manager to use on the annotation or to provide a configured like this
@Component
static class F implements TransactionManagementConfigurer {
private final ReactiveTransactionManager reactiveTransactionManager;
public F(ReactiveTransactionManager reactiveTransactionManager) {
this.reactiveTransactionManager = reactiveTransactionManager;
}
@Override
public TransactionManager annotationDrivenTransactionManager() {
return reactiveTransactionManager;
}
}
but that would be contra intuitive compared to how this is solved with Spring Data repositories.
Having two very distinguishable transaction managers on the context will be the case with the upcoming changes in Spring Boot 2.4 and Spring Data Neo4j 6: It will bring an imperative and a reactive one, thus leading to problems described here.
@mp911de and I hope for respectively suggest a change in the TransactionAspectSupport so that it tries to determine the need for a reactive transaction manager before actually determining one and use the information - if available - to narrow down the selection of the transaction manager in cases where none is configured otherwise.
Comment From: jhoeller
Let's discuss the target scenarios in Boot before we add any extra selection steps in the core transaction support: see https://github.com/spring-projects/spring-boot/issues/22851 - let's see what we can or need to do for 5.3 RC1 then.
Comment From: snicoll
We've decided to stop auto-configuring the Neo4j reactive transaction manager and Spring Boot now looks for the presence of a TransactionManager rather than just a PlatformTransactionManager (or ReactiveTransactionManager). We believe that rather configuring both, Spring Boot should offer a more fine grained way to declare the user intention. This discussion is happening in https://github.com/spring-projects/spring-boot/issues/22692 - I don't have an opinion as whether the core framework should support both transaction managers though but that doesn't seem something we'd like to do out-of-the-box at least.