AOP實(shí)現(xiàn)事務(wù):使用try?c/atch包裹@Transactional
注解的方法浸间,當(dāng)方法出現(xiàn)異常并滿足一定條件時(shí)独榴,在catch里可設(shè)置事務(wù)回滾,沒(méi)有異常則直接提交事務(wù)。
“一定條件”包括:
-
只有異常傳播出了標(biāo)記了
@Transactional
注解的方法嫡丙,事務(wù)才能回滾。在Spring的TransactionAspectSupport里有個(gè) invokeWithinTransaction方法读第,里面就是處理事務(wù)的邏輯曙博。可以看到怜瞒,只有捕獲到異常才能進(jìn)行后續(xù)事務(wù)處理:
image 默認(rèn)情況下父泳,出現(xiàn)RuntimeException(非受檢異常)或Error般哼,Spring才會(huì)回滾事務(wù)。
打開(kāi)Spring的DefaultTransactionAttribute
- 受檢異常一般是業(yè)務(wù)異郴菡或是類似另一種方法的返回值蒸眠,出現(xiàn)這樣的異常可能業(yè)務(wù)還能完成杆融,所以不會(huì)主動(dòng)回滾
-
而Error或RuntimeException代表非預(yù)期結(jié)果楞卡,應(yīng)回滾
image
反面教材
注冊(cè)用戶:
-
createUserError1會(huì)拋RuntimeException,但方法內(nèi)的catch所有異常:
image - createUserError2脾歇,注冊(cè)用戶同時(shí)會(huì)有一次
otherTask
文件讀蒋腮,若讀文件失敗,希望用戶注冊(cè)的DB操作回滾藕各。這里雖無(wú)捕獲異常池摧,但因otherTask拋受檢異常,createUserError2傳播出去的也是受檢異常激况,事務(wù)同樣不回滾:
image -
readFile
image
createUserError1作彤、2這倆方法的實(shí)現(xiàn)和調(diào)用,雖然避開(kāi)了事務(wù)不生效的坑乌逐,但因異常處理不當(dāng)宦棺,文件操作出現(xiàn)異常時(shí)依舊不回滾事務(wù)。
修復(fù)bug
以及如何通過(guò)日志來(lái)驗(yàn)證是否修復(fù)成功黔帕。針對(duì)這2種情況代咸,對(duì)應(yīng)的修復(fù)方法如下。
1 如果希望自己捕獲異常并處理成黄,可手動(dòng)設(shè)置讓當(dāng)前事務(wù)處回滾態(tài)
@Transactional
public void createUserRight1(String name) {
try {
userRepository.save(new UserEntity(name));
throw new RuntimeException("error");
} catch (Exception ex) {
log.error("create user failed", ex);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
查看日志呐芥,事務(wù)確定回滾。
Transactional code has requested rollback
:手動(dòng)請(qǐng)求回滾奋岁。
2 在注解中聲明思瘟,期望遇到所有的Exception都回滾事務(wù)
以突破默認(rèn)不回滾受檢異常的限制。
查看日志闻伶,提示回滾:
[圖片上傳失敗...(image-cd575d-1605664603758)]
該案例有DB操作滨攻、IO操作,在IO操作問(wèn)題時(shí)期望DB事務(wù)也回滾蓝翰,以確保邏輯一致性光绕。
小結(jié)
由于異常處理不正確,導(dǎo)致雖然事務(wù)生效畜份,但出現(xiàn)異常時(shí)沒(méi)回滾诞帐。
Spring默認(rèn)只對(duì)被@Transactional
注解的方法出現(xiàn)RuntimeException
和Error
時(shí)回滾,所以若方法捕獲了異常爆雹,就需要通過(guò)手寫(xiě)代碼處理事務(wù)回滾停蕉。
若希望Spring針對(duì)其他異常也可回滾愕鼓,可相應(yīng)配置@Transactional
注解的rollbackFor
和noRollbackFor
屬性覆蓋Spring的默認(rèn)配置。
有些業(yè)務(wù)可能包含多次DB操作慧起,不一定希望將兩次操作作為一個(gè)事務(wù)菇晃,這時(shí)就需仔細(xì)考慮事務(wù)傳播的配置。