簡介
PROPAGATION_REQUIRED_NEW
:
表示當前方法必須運行在它自己的事務中。一個新的事務將被啟動。如果存在當前事務,在該方法執行期間,當前事務會被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager。
PROPAGATION_NESTED
:
表示如果當前已經存在一個事務,那么該方法將會在嵌套事務中運行。嵌套的事務可以獨立於當前事務進行單獨地提交或回滾。如果當前事務不存在,那么其行為與PROPAGATION_REQUIRED一樣。注意各廠商對這種傳播行為的支持是有所差異的。可以參考資源管理器的文檔來確認它們是否支持嵌套事務。
嵌套事務: 外事物異常,內事物回滾;內事物異常,外事物正常。
案例
PROPAGATION_REQUIRED_NEW案例
serviceOne層中方法
@Transactional(rollbackFor = Exception.class)
public void moneyTestREQUIRED_NEWOne(){
log.info("moneyTestREQUIRED_NEWOne事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//1.查詢病人基本信息
List<TBICXX> tbicxx = basisDao.getTBICXX();
//2.根據CMZH更新TBMZFYHZ
Integer TBMZFYHZCount = tbmzfyhzDao.updateByCMZH("土登", "1903003643");
log.info("更新TBMZFYHZ影響行數{}",TBMZFYHZCount);
try {
propagationBehaviorTwo.moneyTestREQUIRED_NEWTwo();
} catch (Exception e) {
e.printStackTrace();
}
log.info("-------------事物雖然回滾了,但是邏輯繼續執行------------");
}
serviceTwo層中方法
@Transactional(rollbackFor = Exception.class,propagation= Propagation.REQUIRES_NEW)
public void moneyTestREQUIRED_NEWTwo(){
log.info("moneyTestREQUIRED_NEWTwo事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//3.根據CMZH更新TBMZFYMXGH
Integer integer = tbmzfymxghDao.updateByCMZH("土登", "2107000224");
log.info("更新TBMZFYMXGH影響行數{}",integer);
int i=2/0;
}
Test層中方法
/**
* 測試其傳播行為
* PROPAGATION_REQUIRED_NEW:
* 表示當前方法必須運行在它自己的事務中。一個新的事務將被啟動。如果存在當前事務,在該方法執行期間,當前事務會被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager
*
**/
@Test
public void testTransationalPropagationREQUIRED_NEW(){
behaviorOne.moneyTestREQUIRED_NEWOne();
}
運行前
運行后數據庫數據
運行后控制台打印
結論
外事物和內事物是獨立的事物,內事物異常回滾不影響外事物,外事物回滾不影響內事物。
PROPAGATION_NESTED案例
serviceOne層中方法
@Transactional(rollbackFor = Exception.class)
public void moneyTestNESTEDOne(){
log.info("moneyTestNESTEDOne事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//1.查詢病人基本信息
List<TBICXX> tbicxx = basisDao.getTBICXX();
//2.根據CMZH更新TBMZFYHZ
Integer TBMZFYHZCount = tbmzfyhzDao.updateByCMZH("三筒", "1903003643");
log.info("更新TBMZFYHZ影響行數{}",TBMZFYHZCount);
try {
propagationBehaviorTwo.moneyTestNESTEDTwo();
} catch (Exception e) {
// 為了避免 org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only 該異常產生
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
e.printStackTrace();
}
int i=2/0; //JJ句
log.info("-------------事物雖然回滾了,但是邏輯繼續執行------------");
}
serviceTwo層中方法
@Transactional(rollbackFor = Exception.class,propagation= Propagation.NESTED)
public void moneyTestNESTEDTwo(){
log.info("moneyTestNESTEDTwo事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//3.根據CMZH更新TBMZFYMXGH
Integer integer = tbmzfymxghDao.updateByCMZH("三筒", "2107000224");
log.info("更新TBMZFYMXGH影響行數{}",integer);
int i=2/0; //KK句
}
運行前數據庫數據
--------------KK句注釋調運行結果,JJ句開啟---------------
運行后數據庫數據
運行后控制台打印
--------------JJ句注釋調運行結果,KK句開啟---------------
運行后數據庫數據
運行后控制台打印
結論
嵌套事物: 運行的是同一個事物,外事物提交,內事物回滾是通過設置回滾點來實現,具體實現過程參考:
https://www.jianshu.com/p/2f79ee33c8ad