Mybatis-plus多數據源方法添加事務,數據源切換失敗


一、問題情況:

1.項目中使用的多數據源,各個方法上加了@DataSource注解,對於批量操作,需要做使用事務保持批操作的一致性。
2.運行測試時,發現insert報錯,數據源並未切換至second。
3.核心代碼如下:
@Service("chargeAccountDetailService")
public class ChargeAccountDetailServiceImpl implements ChargeAccountDetailService {
    @Autowired
    ChargeAccountDetailMapper detailMapper;
    
    @DataSource(name = "second")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertAccountDetailBatch(Long accountId, List<ChargeAccountDetail> list, String tenant) {
        return detailMapper.insertAccountDetailBatch(accountId, list, tenant);
    }
}
@Override
@Transactional(rollbackFor = Exception.class)
public void run(Long[] jobIds) {
   for(Long jobId : jobIds){
      ScheduleUtils.run(scheduler, this.selectById(jobId));
   }
}

二、相關疑問:

1.其他的未加事務的數據源切換都是正常的,為什么加上@Transactional(rollbackFor = Exception.class)注解會導致切換數據源失敗?
@Transaction的默認propagation=Propagation.REQUIRED,即事務的傳播屬性是,存在事務加入當前事務,不存在就創建事務,
因為在開啟事務的同時,會從數據庫連接池獲取數據庫連接。但是事務@Transaction的默認傳播屬性,並不是新建一個事務,也就沒有重新獲取數據源連接。
而在事務內的所有數據庫操作,都是在事務連接建立之后進行的,所以會產生數據源沒有切換的問題。
2.如何保證數據源切換正常,且事務正常?
要切換數據源,則必須是一個新的事務,所以需要修改事務的傳播數據,使其創建一個新的事務,獲取新的數據庫連接。
可以在 @Trasactional注解上修改propagation = Propagation.REQUIRES_NEW

三、解決問題:

1.使用@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)即可,代碼如下:
@Service("chargeAccountDetailService")
public class ChargeAccountDetailServiceImpl implements ChargeAccountDetailService {

    @Autowired
    ChargeAccountDetailMapper detailMapper;

    @DataSource(name = "second")
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @Override
    public int insertAccountDetailBatch(Long accountId, List<ChargeAccountDetail> list, String tenant) {
        return detailMapper.insertAccountDetailBatch(accountId, list, tenant);
    }
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
表示新建事務,如果當前存在事務,把當前事務掛起。

四、擴展:

1.對於切換數據源的方法,需要使用事務,請盡可能使用@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)。
2.多數據源切換,方法調用先后順需,內部方法切換數據源等見參考連接內容。

五、參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM