首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事务,和R2DBC

事务,和R2DBC
EN

Stack Overflow用户
提问于 2020-03-25 13:04:25
回答 2查看 1.8K关注 0票数 1

我正在尝试迁移使用JDBC模板到R2DBC的Spring项目2.3.0.M3版本。该项目还使用了Liquibase,因此我无法完全摆脱JDBC。我在项目中有spring starter r2dbc和spring starter依赖项,在尝试运行我的一个测试时,我得到了以下异常:

代码语言:javascript
复制
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中定义如下:

代码语言:javascript
复制
    @Bean
    @ConditionalOnMissingBean(ReactiveTransactionManager.class)
    public R2dbcTransactionManager connectionFactoryTransactionManager(ConnectionFactory connectionFactory) {
        return new R2dbcTransactionManager(connectionFactory);
    }

在Spring类DataSourceTransactionManagerAutoConfiguration:中,bean transactionManager的定义如下

代码语言:javascript
复制
   @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方法中有这一行代码:

代码语言:javascript
复制
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);

由于事务管理器类型DataSourceTransactionManager和R2dbcTransactionManager都实现了TransactionManager接口,因此将匹配上面提到的事务管理器bean,并且会发生错误。

我现在想听听是否有人已经解决或解决了这个问题?

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-25 13:37:01

在M. Deinum回答(谢谢!)的启发下,我将以下步骤应用到我的项目中,之前失败的测试现在成功地运行了:

删除spring-boot-starter-jdbc dependency.

  • Add,依赖于spring-jdbc.

  • Add,依赖于HikariCP (com.zaxxer).

  • Add spring.liquibase用户和密码属性(我已经拥有url和更改日志properties).

  • Remove all spring.datasource属性(我有url和drive-class-name).

)。

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

更新:

此外,我在测试中使用了测试容器,无法分配静态端口。为了能够在Liquibase上配置数据库端口,我重写了一个类型为SpringLiquibase的bean名称液化库,并在清算bean创建方法中创建了一个DataSource (不公开为bean),并将其设置在清算bean上。

票数 1
EN

Stack Overflow用户

发布于 2020-05-17 17:59:17

spring-boot-starter-jdbcspring-boot-starter-data-r2dbc共存是可能的.有一个类org.springframework.transaction.annotation.TransactionManagementConfigurer可以用来解决冲突。当r2dbc出现时,SpringBoot2.3.0似乎会禁用自动数据源配置。可以手动导入org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration类,使两者共存。

代码语言:javascript
复制
@Bean
TransactionManagementConfigurer transactionManagementConfigurer(ReactiveTransactionManager reactiveTransactionManager) {
    return new TransactionManagementConfigurer() {
        @Override
        public TransactionManager annotationDrivenTransactionManager() {
            return reactiveTransactionManager;
        }
    };
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60849453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档