@DS("slave") 多數據源兼容事務問題解決方案

SpringBoot項目中用到多數據源,在方法上又必須加事務處理,此時可以對使用了@DS的方法或類添加@Transactional並添加事務隔離級別

舉例:

1、這是一個方法,方法內需要實現多數據源查詢

 2、在該方法中判斷查詢哪一個數據源:

 3、此時可以將slave數據源的service類添加

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

 

原因解析

解決辦法就是將原本的一個事務拆分成兩個事務。你可以試一下,只在主方法中加事務,你會發現在切面裏看數據源切換了,但事務內的數據源依然是舊的,這樣就會報出XXX表找不到的問題。那麼到底是什麼原因導致一個事務內的數據源沒有隨着@DS(“slave”)註解做出動態數據源切換呢?

  1. 因爲SPRING在開啓事務的同時,會去數據庫連接池拿數據庫連接。如果僅在主方法上添加@TRANSACTIONAL,那麼,TRANSACTIONINTERCEPTOR 會使用 SPRING DATASOURCETRANSACTIONMANAGER 創建事務,並將事務信息(獲取數據源CONNECTION連接,此時獲取到的數據源是默認配置的BASE數據源信息)連接信息,通過 THREADLOCAL 綁定在當前線程。
  2. 此時當前線程事務綁定的連接信息是BASE數據源,當我們在內層切換數據源方法上使用@DS切換數據源,並沒有重新開啓新事務,沒有改變當前線程事務的連接信息,僅僅是做了一次攔截,改變了DATASOURCEHOLDER的棧頂DATASOURCE,對於整個事務的連接是沒有影響的,所以會產生數據源沒有切換的問題。
  3. 所以我這裏的解決辦法是,將保證住方法操作數據完整性的事務,拆解成兩個事務,在切換數據源方法類上,除了添加切換數據源的註解@DS(“DB2”),再添加@TRANSACTIONAL(PROPAGATION = PROPAGATION.REQUIRES_NEW, ROLLBACKFOR = EXCEPTION.CLASS),新建開一個事務,獲取新數據源CONNECTION連接。

 

 

在使用@DS註解時,有如下注意事項:

  1. 不能使用事務,否則數據源不會切換,使用的還是第一次加載的數據源;
  2. 第一次加載數據源之後,第二次、第三次…操作其它數據源,如果數據源不存在,使用的還是第一次加載的數據源;
  3. 數據源名稱不要包含下劃線,否則不能切換。

 

一句話總結:用到多數據源的方法不能使用事務,如果主方法必須使用事務,那麼slave數據源方法上或類上需要添加 下面註解。

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章