Spring Boot 和 Mybatis 项目中多个数据源时的 NoUniqueBeanDefinitionException
NoUniqueBeanDefinitionException when multiple datasources in Spring Boot and Mybatis project
在Spring Boot 和Mybatis 项目中配置多个数据源时,出现以下异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type
'org.springframework.transaction.PlatformTransactionManager'
available: expected single matching bean but found 2:
primaryTx,secondTx at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041)
~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:384)
~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] at
com.sun.proxy.$Proxy86.findByDomain(Unknown Source) ~[na:na]
项目开始
@SpringBootApplication( exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
})
@EnableTransactionManagement
public class BookSystemApplication {
}
数据源配置
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
交易
@Configuration
public class TransactionConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primary;
@Autowired
@Qualifier("secondDataSource")
private DataSource second;
@Bean(name="primaryTx")
public PlatformTransactionManager primaryTransaction() {
return new DataSourceTransactionManager(primary);
}
@Bean(name="secondTx")
public PlatformTransactionManager secondTransaction() {
return new DataSourceTransactionManager(second);
}
}
这里的问题是您将两个 beans
定义为 datasource
并将两个 bean 定义为 TransactionManager
但您没有指定其中一个是 primary
一,这行不通,因为 Spring
需要一个 datasource
bean 和一个 TransactionManager
bean 被定义为主要 如果定义了多个.
您在这里应该做的是将您的数据源之一 beans
和您的 TransactionManager beans
之一定义为 Primary
,以便 Spring 可以 运行 正确,为此你需要使用 @Primary
注释 .
@Bean(name = "primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
首先感谢√的解答,完美解决了我的问题
而且我可以向某人提供 thinking.Unnecessary @Primary
的另一种方式,您可以在您的服务中定义 @Transactional("primaryTx")
。
像这样:
@Override
@Transactional("primaryTx")
public Test update() {
Test entity = new Test();
entity.setId(1L);
entity.setPhone("19900000050");
return testRepository.save(entity);
}
在Spring Boot 和Mybatis 项目中配置多个数据源时,出现以下异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 2: primaryTx,secondTx at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:384) ~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272) ~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] at com.sun.proxy.$Proxy86.findByDomain(Unknown Source) ~[na:na]
项目开始
@SpringBootApplication( exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
})
@EnableTransactionManagement
public class BookSystemApplication {
}
数据源配置
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
交易
@Configuration
public class TransactionConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primary;
@Autowired
@Qualifier("secondDataSource")
private DataSource second;
@Bean(name="primaryTx")
public PlatformTransactionManager primaryTransaction() {
return new DataSourceTransactionManager(primary);
}
@Bean(name="secondTx")
public PlatformTransactionManager secondTransaction() {
return new DataSourceTransactionManager(second);
}
}
这里的问题是您将两个 beans
定义为 datasource
并将两个 bean 定义为 TransactionManager
但您没有指定其中一个是 primary
一,这行不通,因为 Spring
需要一个 datasource
bean 和一个 TransactionManager
bean 被定义为主要 如果定义了多个.
您在这里应该做的是将您的数据源之一 beans
和您的 TransactionManager beans
之一定义为 Primary
,以便 Spring 可以 运行 正确,为此你需要使用 @Primary
注释 .
@Bean(name = "primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
首先感谢√的解答,完美解决了我的问题
而且我可以向某人提供 thinking.Unnecessary @Primary
的另一种方式,您可以在您的服务中定义 @Transactional("primaryTx")
。
像这样:
@Override
@Transactional("primaryTx")
public Test update() {
Test entity = new Test();
entity.setId(1L);
entity.setPhone("19900000050");
return testRepository.save(entity);
}