JPA事務中的異常最後不也拋出了,為什麼沒被catch到而導致回滾?
- 2021 年 7 月 9 日
- 筆記
上周,我們通過這篇文章《為什麼catch了異常,但事務還是回滾了?》來解釋了,之前test4為什麼會回滾的原因。
但還是收到了很多沒有理解的回饋,主要是根據前文給出的線索去跟蹤,是獲得到了回滾的標示和異常,而讓大家不理解的是,javax.validation.ConstraintViolationException
異常不是最後也向外拋出了,那麼為什麼test4里catch沒有能夠捕獲到呢?
其實這個問題並不難解釋,下面就通過這篇文章,做個小實驗,幫助大家進一步理解大家的這個疑問!
如果你還不了解這篇文章在討論什麼,建議先看之前的兩篇:
動手嘗試一下
由於@Transactional
註解的事務是通過切面來實現的,所以要通過源碼去了解整個過程,可能還是不容易理解。
所以,這裡教大家一個簡單方法來理解這次test4的catch為什麼沒有捕獲異常。
我們通過類似下面的方式,給test4多加一些日誌資訊和斷點:
同時,記得也在上一篇說到的事務提交入口,也加上斷點。
然後嘗試觸發test4的執行,通過DEBUG,我們都可以觀察到:
test4中我們加的斷點,除了47行沒進入,其他的一次性都執行完了。然後才進入了org.springframework.orm.jpa.JpaTransactionManager
的doCommit
方法。
所以,前文中我們跟蹤的事務回滾所拋出的異常,其實是在test4中的try-catch塊執行完之後才拋出的,所以內部的這個catch是無法捕獲異常的,這裡完全就是catch了個寂寞。
通過日誌,我們也能觀察到這樣的執行順序:
好了,通過這樣來看,是不是要比之前有進一步的理解了呢?如果您還想跟深入的了解事務的底層運行機制,一定要debug一下源碼,自己過一遍,理解會深刻哦!如果你還有其他疑問,歡迎加入我們的Spring技術交流群,參與交流與討論,一起學習與進步!如果您正在學習Spring Boot,我的免費教程一直在持續連載,歡迎關注Spring Boot 2.x基礎教程。
歡迎關注我的公眾號:程式猿DD,分享外面看不到的乾貨與思考!