Spring Boot 項目中配置多數(shù)據(jù)源@Transactional注解失效問題

現(xiàn)象 :

當(dāng)一個Spring Boot 項目在配置了多個數(shù)據(jù)源 , 在編寫Service層方法的時候 , 直接在service方法的上添加的@Transactional直接實現(xiàn)事務(wù)管理的方式是失效的 .

原因 :

以最近接觸到的一個持久層框架使用的是Jpa的項目為例 , 該項目通過硬編碼(配置類)的方式 , 在項目中配置了兩個不同的數(shù)據(jù)源 , 所以這個項目分別根據(jù)兩個數(shù)據(jù)源配置了各自的事務(wù)管理器PlatformTransactionManager , 如下 :

第一個數(shù)據(jù)源的事務(wù)管理器配置類 :

@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());
    }
}

第二個數(shù)據(jù)源事務(wù)管理器配置類 :

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryTwo", //實體管理
        transactionManagerRef = "transactionManagerTwo", //事務(wù)管理
        basePackages = {"com.xxx"} //數(shù)據(jù)源所應(yīng)用到的包
)
public class WeeklyDataSourceConfig {

    @Autowired
    @Qualifier("weeklyDataSource")
    private DataSource weeklyDataSource;
    
    //這里省略部分配置 ...
    
    @Primary
    @Bean(name = "transactionManagerTwo")
    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
    }
}

可以看到第二個事務(wù)管理器的Bean方法上添加了@Primary注解 , 所以在通過PlatformTransactionManager類型注入事務(wù)管理器的bean時 , 默認(rèn)是根據(jù)類型去注入 , 如果該類型有多個Bean , 如不通過bean的名字去注入 , 則默認(rèn)是會注入被@Primary標(biāo)識的bean的 ;

所以在這個項目中 , 當(dāng)在業(yè)務(wù)層方法添加@Transactional注解時 , 默認(rèn)是調(diào)用了transactionManagerTwo這個bean , 而我在編寫service層的方法時 , 調(diào)用的是第一個數(shù)據(jù)源對應(yīng)的Dao層方法 , 所以直接添加@Transactional是不能實現(xiàn)事務(wù)管理的 ,

解決辦法 :

需要在使用@Transactional注解時指定使用的事務(wù)管理器的bean的名字 , 比如我這里調(diào)用的是第一個數(shù)據(jù)源的dao層方法 , 所以需要指定對應(yīng)的事務(wù)管理器 : @Transactional(transactionManager = "transactionManagerOne") .

@Transactional(transactionManager = "transactionManagerOne")
    public void deleteById(Integer Id) {
       //...
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容