我正在尝试将使用 JDBC 模板的 Spring Boot 项目版本 2.3.0.M3 迁移到 R2DBC。该项目还使用 Liquibase,因此我无法完全摆脱 JDBC。我在项目中同时拥有 spring-boot-starter-data-r2dbc 和 spring-boot-starter-jdbc 依赖项,在尝试运行我的一项测试时出现以下异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 2: transactionManager,connectionFactoryTransactionManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1180)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:416)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:480)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:335)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
...
bean connectionFactoryTransaction 管理器在 Spring 类 R2dbcTransactionManagerAutoConfiguration 中定义如下:
@Bean
@ConditionalOnMissingBean(ReactiveTransactionManager.class)
public R2dbcTransactionManager connectionFactoryTransactionManager(ConnectionFactory connectionFactory) {
return new R2dbcTransactionManager(connectionFactory);
}
bean transactionManager 在 Spring 类 DataSourceTransactionManagerAutoConfiguration 中是这样定义的:
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
DataSourceTransactionManager transactionManager(DataSource dataSource,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
return transactionManager;
}
可以看出,@ConditionalOnMissingBean 注释包含不同的类型,这将导致创建两个 bean 的实例。但是,在 Spring 类 TransactionAspectSupport 中,determineTransactionManager 方法中有这行代码:
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
由于 DataSourceTransactionManager 和 R2dbcTransactionManager 这两种事务管理器类型都实现了 TransactionManager 接口,因此上述两个事务管理器 bean 都会匹配并发生错误。
我现在正在联系是否有人设法解决或解决此问题?
提前致谢!