事务,Spring Boot Starter JDBC和R2DBC

问题描述 投票:0回答:1

我正在尝试将使用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事务管理器在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中,defineTransactionManager方法中包含以下代码行:

defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);

由于两种事务管理器类型DataSourceTransactionManager和R2dbcTransactionManager均实现TransactionManager接口,因此上述两个事务管理器bean都将匹配,并且将发生错误。

我现在正在与外界联系,以了解是否有人设法解决或解决此问题?预先感谢!

spring spring-boot spring-jdbc spring-data-r2dbc
1个回答
0
投票

[得益于M. Deinums的回答(谢谢!),我将以下步骤应用于我的项目,并且之前失败的测试现在可以成功运行:

  • 删除spring-boot-starter-jdbc依赖项。
  • 向spring-jdbc添加依赖项。
  • 向HikariCP(com.zaxxer)添加依赖项。
  • 添加spring.liquibase用户和密码属性(我已经具有url和change-log属性)。
  • 删除所有spring.datasource属性(我有url和drive-class-name)。

我已经定义了spring.r2dbc属性用户名,密码和url,不需要更改。

© www.soinside.com 2019 - 2024. All rights reserved.