首先,Spring 的事務機制:
默認spring事務只在發生未被捕獲的 RuntimeExcetpion 時纔回滾。
什麼意思呢?就是被攔截的方法拋出異常,但不能捕獲處理,這樣 【AOP代理】能捕獲異常,才能進行回滾。
所以,若要發生異常時,可以進行正確的回滾:
1)service 層處理,不要進行異常捕獲,或者捕獲了直接拋出 RuntimeException,讓上層 action 繼續捕獲處理。
2)service 層捕獲後,catch 中添加 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 觸發手動回滾,這樣上層就無需捕獲處理。
@Transactional 事務註解需要注意:
1)只能註解到 public 方法上,這樣纔會開啓事務。
2)不能被同類,內部方法調用,會導致事務失效,不會回滾。(由於使用 Spring AOP代理造成 )