多数据源导致的找不到事务管理器的问题 @Primary

问题:

在使用多数据源,jpa 和 mybatis 相结合的使用中,新加入的数据源的配置后,旧数据源的查询报错。

错误日志:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: 
   expected single matching bean but found 2: 
        1DatasourceTransactionManager,2PerfTracsactionManager

	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:370)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor.invoke(DynamicDataSourceAnnotationInterceptor.java:50)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
	at com.sun.proxy.$Proxy231.selectAll(Unknown Source)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)

解决办法:

在主数据源的事务管理器上增加注解:

@Primary

备注:

在使用多数据源的时候,在配置默认主数据源的时候:

PlatformTransactionManagerSqlSessionFactory 上加上加上 @Primary 注解。

@Primary: 自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于Spring Boot的多数据切换,通过事务管理对多个数据切换进行事务管理的代码案例: 首先,在application.properties文件中配置数据: ``` # 数据1 spring.datasource.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 数据2 spring.datasource.datasource2.url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.datasource2.username=root spring.datasource.datasource2.password=123456 spring.datasource.datasource2.driver-class-name=com.mysql.jdbc.Driver ``` 然后,创建两个数据的配置类: ``` @Configuration public class DataSourceConfig { // 数据1配置 @Bean(name = "dataSource1") @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource1() { return DataSourceBuilder.create().build(); } // 数据2配置 @Bean(name = "dataSource2") @ConfigurationProperties(prefix = "spring.datasource.datasource2") public DataSource dataSource2() { return DataSourceBuilder.create().build(); } } ``` 接着,在需要使用数据的Service类中,使用@Qualifier注解指定数据: ``` @Service public class UserServiceImpl implements UserService { @Autowired @Qualifier("dataSource1") private DataSource dataSource1; @Autowired @Qualifier("dataSource2") private DataSource dataSource2; @Override @Transactional public void addUser(User user) { // 使用数据1插入数据 JdbcTemplate jdbcTemplate1 = new JdbcTemplate(dataSource1); jdbcTemplate1.update("insert into user(name, age) values (?, ?)", user.getName(), user.getAge()); // 使用数据2插入数据 JdbcTemplate jdbcTemplate2 = new JdbcTemplate(dataSource2); jdbcTemplate2.update("insert into user(name, age) values (?, ?)", user.getName(), user.getAge()); } } ``` 最后,通过@Primary注解指定默认数据,并在事务管理中使用@Transactional注解进行事务管理: ``` @Configuration @EnableTransactionManagement public class TransactionConfig { // 默认数据为dataSource1 @Primary @Bean(name = "dataSource") public DataSource dataSource(@Qualifier("dataSource1") DataSource dataSource1, @Qualifier("dataSource2") DataSource dataSource2) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("dataSource1", dataSource1); targetDataSources.put("dataSource2", dataSource2); DynamicDataSource dynamicDataSource = new DynamicDataSource(); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(dataSource1); return dynamicDataSource; } // 事务管理 @Bean(name = "transactionManager") public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } ``` 以上就是基于Spring Boot的多数据切换,通过事务管理对多个数据切换进行事务管理的代码案例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值