事務傳播機制實驗中出現的問題
阿新 • • 發佈:2022-05-25
在測試 REQUIRED 和 NESTED 區別的時候,寫了如下一段程式碼:
然後在測試的時候,如果不捕獲異常的話,無論被呼叫方法的傳播機制是 REQUIRED 還是 NESTED,user 和 login_ticket 中的 status 都還是為 0(回滾)。
但是捕獲異常的話,兩種機制都不回滾,2 個表中的 status 都變成了 1。
這是為啥呢?
在技術交流群裡請教了大佬之後,終於明白了(雖然也是一知半解)。
原來我把兩個方法寫在了同一個類裡,這樣當第一個方法被呼叫時,走了 AOP 代理;然後去呼叫第二個方法的時候,因為是同一個類的方法,所以方法內部呼叫的時候,直接是 this.xxx(),沒走代理。即,代理內部呼叫本類的方法的時候不會重新走一遍代理 。不走代理的話,需要代理才能生效的那些功能就會失效。所以下面的這個方法就成了一個普通方法。實際的效果如下:
這個時候,雖然有異常,但是被捕獲了,所以事務不會回滾。
需要改成下面的形式:
(這裡大佬說,可以在一個 Service 中注入另一個 Service,他公司專案中有這種寫法)
把被呼叫方法寫到另一個類(BetaService)中:
把 2 個方法寫在不同的類中,就能實現 spring事務傳播機制NESTED和REQUIRED的區別 這篇部落格中的效果。
即,不捕獲異常,無論 REQUIRED 還是 NESTED,2 個事務都會回滾;捕獲異常,REQUIRED 都會回滾,NESTED 主事務不會回滾,巢狀事務會回滾。具體原理可以參照上面的部落格。
(不得不佩服大佬實在是太強了。Spring 底層原理日後還得多加學習)