[英]Transactions, Spring Boot Starter JDBC & R2DBC
我正在嘗試將使用 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 都會匹配,並且會發生錯誤。
我現在正在聯系是否有人設法解決或解決了這個問題?
提前致謝!
受 M. Deinums 回答的啟發(謝謝!),我將以下步驟應用於我的項目,之前失敗的測試現在成功運行:
我定義了 spring.r2dbc 屬性用戶名、密碼和 url,我不需要更改。
更新:
另外,我在測試中使用了Testcontainers,無法分配靜態端口。 為了能夠在 Liquibase 上配置數據庫端口,我覆蓋了一個類型為 SpringLiquibase 的 bean 名稱 liquibase 並在 liquibase bean 創建方法中創建了一個 DataSource(不公開為 bean)並將其設置在 liquibase bean 上。
spring-boot-starter-jdbc
和spring-boot-starter-data-r2dbc
共存。 有一個類org.springframework.transaction.annotation.TransactionManagementConfigurer
可用於解決沖突。 當 r2dbc 存在時,Spring Boot 2.3.0 似乎禁用了自動數據源配置。 可以手動導入org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
類以使兩者共存。
@Bean
TransactionManagementConfigurer transactionManagementConfigurer(ReactiveTransactionManager reactiveTransactionManager) {
return new TransactionManagementConfigurer() {
@Override
public TransactionManager annotationDrivenTransactionManager() {
return reactiveTransactionManager;
}
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.