在Spring Boot和Mybatis项目中配置多个数据源时,出现以下异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException:否类型的限定bean'org.springframework.transaction.PlatformTransactionManager'可用:应为单个匹配bean,但找到2:主Tx,次Txorg.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041(~[spring-bans-4.3.13.REASE.jar:4.3.13.RELEASE]org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345(~[spring-bans-4.3.13.REASE.jar:4.3.13.RELEASE]org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340(~[spring-bans-4.3.13.REASE.jar:4.3.13.RELEASE]org.springframework.transaction.enterceptor.TransactionAspectSupport.definisheTransactionManager(TransactionAspectSupport.java:384(~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEAE]org.springframework.transaction.intercept.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272(~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEAE]org.springframework.transaction.interceptor.TransactionInterceptor.ininvoke(TransactionInterceptor.java:96(~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEAE]org.springframework.aop.framework.ReflectiveMethodInvocation.prough(ReflectiveMethodInvocation.java:179(~[spring-aop-4.3.13.REASE.jar:4.3.13.RELEASE]org.springframework.aop.framework.JdkDynamicAopProxy.invoke~[spring-aop-4.3.13.REASE.jar:4.3.13.RELEASE]com.sun.proxy.$Proxy86.findByDomain(未知来源(~[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
和一个TransactionManagerbeans
定义为Primary
,以便Spring能够正确运行,为此,您需要使用@Primary
注释。
@Bean(name = "primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
请参阅文档中Spring的配置两个数据源部分。
首先,谢谢√答案,它完美地解决了我的问题。
我可以提供另一种思考方式。对某人来说不必要的@Primary
,您可以在服务中定义为@Transactional("primaryTx")
。
像这样:
@Override
@Transactional("primaryTx")
public Test update() {
Test entity = new Test();
entity.setId(1L);
entity.setPhone("19900000050");
return testRepository.save(entity);
}