美文网首页
Spring Boot 项目中配置多数据源@Transactio

Spring Boot 项目中配置多数据源@Transactio

作者: studymachine | 来源:发表于2019-03-27 00:09 被阅读0次

    现象 :

    当一个Spring Boot 项目在配置了多个数据源 , 在编写Service层方法的时候 , 直接在service方法的上添加的@Transactional直接实现事务管理的方式是失效的 .

    原因 :

    以最近接触到的一个持久层框架使用的是Jpa的项目为例 , 该项目通过硬编码(配置类)的方式 , 在项目中配置了两个不同的数据源 , 所以这个项目分别根据两个数据源配置了各自的事务管理器PlatformTransactionManager , 如下 :

    第一个数据源的事务管理器配置类 :

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryOne",
            transactionManagerRef = "transactionManagerOne",
            basePackages = {"com.xxx.xxx"} 
    )
    public class OneDataSourceConfig {
    
        @Autowired
        @Qualifier("oneDataSource")
        private DataSource oneDataSource;
        
    
       // .. 这里省略部分bean配置
    
        @Bean(name = "transactionManagerOne")
        public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
        }
    }
    

    第二个数据源事务管理器配置类 :

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryTwo", //实体管理
            transactionManagerRef = "transactionManagerTwo", //事务管理
            basePackages = {"com.xxx"} //数据源所应用到的包
    )
    public class WeeklyDataSourceConfig {
    
        @Autowired
        @Qualifier("weeklyDataSource")
        private DataSource weeklyDataSource;
        
        //这里省略部分配置 ...
        
        @Primary
        @Bean(name = "transactionManagerTwo")
        public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
        }
    }
    
    

    可以看到第二个事务管理器的Bean方法上添加了@Primary注解 , 所以在通过PlatformTransactionManager类型注入事务管理器的bean时 , 默认是根据类型去注入 , 如果该类型有多个Bean , 如不通过bean的名字去注入 , 则默认是会注入被@Primary标识的bean的 ;

    所以在这个项目中 , 当在业务层方法添加@Transactional注解时 , 默认是调用了transactionManagerTwo这个bean , 而我在编写service层的方法时 , 调用的是第一个数据源对应的Dao层方法 , 所以直接添加@Transactional是不能实现事务管理的 ,

    解决办法 :

    需要在使用@Transactional注解时指定使用的事务管理器的bean的名字 , 比如我这里调用的是第一个数据源的dao层方法 , 所以需要指定对应的事务管理器 : @Transactional(transactionManager = "transactionManagerOne") .

    @Transactional(transactionManager = "transactionManagerOne")
        public void deleteById(Integer Id) {
           //...
        }
    

    相关文章

      网友评论

          本文标题:Spring Boot 项目中配置多数据源@Transactio

          本文链接:https://www.haomeiwen.com/subject/aboovqtx.html