1. 程式人生 > >關於Spring的@Transactional註解失效以及事務無法回滾問題

關於Spring的@Transactional註解失效以及事務無法回滾問題

@Transactional失效問題

最近寫的專案中需要一個service中的部分事務執行完就被commit,但是部分service需要失敗回滾。因此寫在一個大的service中並且加上@Transactional顯然是無法滿足需求的。
因此這是需要把原先的一個service服務拆分,如原先的serviceA被拆分成serviceA和ServiceB,並且在ServiceB上打@Transactional註解,而serviceA未打註解。
整體執行流程是由controller呼叫serviceA,再經serviceA呼叫serviceB。但是在執行過程發現serviceB中的事務語句在執行後就會被立馬提交,事務控制未生效。
翻閱資料有的說因為context:component-scan重複載入導致失效,但是sprintg配置中掃描service的包無重複。於是抱著試試的心態在serviceA上繼續新增@Transactional註解,返現這是serviceB的事務生效。
也就是說帶事務註解的serviceA被其他service呼叫時,如果想要生效,最外層的也得加上@Transactional註解。

@Transactional,失敗無法回滾

緊接著上個問題說,serviceB中的事務生效後,在執行遇到異常時,捕獲並且丟擲自定的異常InvalidException extends Exception。發現執行的sql事務無法回滾。無奈只能在註解上加上rollbackFor = InvalidException.class。但是為了弄明白原因,斷點除錯到spring底層程式碼,發現這麼一句程式碼
return (ex instanceof RuntimeException || ex instanceof Error);
就是說要想事務回滾你的異常要麼派生自RuntimeException或者Error,於是把InvalidException改成整合RuntimeExcepiton,並且把註解中的rollbackFor去除,發現也是可以正常回滾。