当Spring Boot和Mybatis项目中有多个数据源时,会出现NoUniqueBeanDefinitionException

时间:2018-07-12 13:28:16

标签: java spring-boot mybatis

在Spring Boot和Mybatis项目中配置多个数据源时,发生以下异常:

  

org.springframework.beans.factory.NoUniqueBeanDefinitionException:否   类型的合格豆   'org.springframework.transaction.PlatformTransactionManager'   可用:预期的单个匹配bean,但发现2:   primaryTx,secondTx在   org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041)   〜[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)   〜[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)   〜[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:384)   〜[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)   〜[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)   〜[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)   〜[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]在   org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)   〜[spring-aop-4.3.13.RELEASE.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);
    }
}

2 个答案:

答案 0 :(得分:1)

这里的问题是,您将两个beans定义为datasource,将两个bean定义为TransactionManager,但是您没有指定其中一个是primary这将不起作用,因为如果定义了多个 Spring需要一个datasource bean和一个TransactionManager bean被定义为primary ,< / em>。

您应该在此处定义一个数据源beans和一个TransactionManager beansPrimary,这样Spring才能正确运行,您将需要使用 @Primary批注

@Bean(name = "primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
    return DataSourceBuilder.create().build();
}

请参阅文档中的the Spring's Configure two datasources section

答案 1 :(得分:0)

首先,感谢√回答,它很好地解决了我的问题。

我可以提供另一种思维方式。不必要的@Primary可以让您在服务中定义为@Transactional("primaryTx")

像这样:

    @Override
    @Transactional("primaryTx")
    public Test update() {
        Test entity = new Test();
        entity.setId(1L);
        entity.setPhone("19900000050");
        return testRepository.save(entity);
    }