springboot@Transactional事務不生效的幾種解決方案

springboot事務不生效的幾種解決方案


最近在業務中遇到了很奇怪的場景,在加上 @Transactional註解後,插入2條數據,如果第二條出異常了,第一條不會回滾,排查了很久,上網也找資料看了很久,問題得以解決,總結了事務不生效的幾點可能的原因:

  • mysql的MyISAM引擎不支持回滾,如果需要自動回滾事務,需要將mysql的引擎設置成InnoDB;
  • 在業務中拋出異常時,本應該被事務管理器捕獲的異常,被手動catch處理了,或者事務結果未滿足具體業務需求的,如果需要手動catch異常做業務處理,需要在catch裏手動回滾事務TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(),或者在catch中主動拋出異常throw new RuntimeException();.
  • 默認的spring事務只會捕獲RuntimeException,如果是非運行時異常也需要進行事務回滾的話,可以在@Transactional註解中加上rollbackfor = Exception.class屬性;
  • 項目中沒有配置事務管理器(大坑!我遇到的就是這個),需要在配置類或者配置文件中配置,以本人的配置類爲例,因爲項目是多數據源的,所以要區別配置不同數據源的事務管理器.
  • 數據源一:
    @Bean(name = "detDataSource")
    public DataSource getDataSource() {
        return createDataSource();
    }
    @Bean(name = "detTransactionManager")
    public PlatformTransactionManager txManager(@Qualifier("detDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
  • 數據源二:
@Primary
   @Bean(name = "shardDataSource")
   public DataSource getDataSource() {
       return buildDataSource();
   }
   @Bean(name = "shardTransactionManager")
   public PlatformTransactionManager txManager(@Qualifier("shardDataSource") DataSource dataSource) {
       return new DataSourceTransactionManager(dataSource);
   }

可以看到,兩個事務管理器配置了不同的beanName,接下來只需要 在需要事務控制的位置加上該事務管理器的name就可以完美解決啦!

@Override
   @Transactional(value = "detTransactionManager",rollbackFor = Exception.class)
   public int updateOrInsert(BaseRequest<BankTemplateDto> param) {
發佈了5 篇原創文章 · 獲贊 7 · 訪問量 2785
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章