1. 程式人生 > >spring boot @Transactional註解事務不回滾不起作用無效

spring boot @Transactional註解事務不回滾不起作用無效

使用資料庫新增兩張表是, 一個事務已提交,但例外一個事務已報錯的情況:

當@Transactional不起作用如何排查問題。

可以按照以下幾個步驟逐一確認:

1、首先要看資料庫本身對應的庫、表所設定的引擎是什麼。MyIsam不支援事務,如果需要,則必須改為InnnoDB。

2、@Transactional所註解的方法是否為public

如果應用在protected、private或者 package可見度的方法上,也不會報錯,不過事務設定不會起作用。

3、@Transactional所註解的方法所在的類,是否已經被註解@Service或@Component等。

4、需要呼叫該方法,且需要支援事務特性的呼叫方是在在 @Transactional所在的類的外面。注意:類內部的其他方法呼叫這個註解了@Transactional的方法,事務是不會起作用的。

注意:service類標籤(一般不建議在介面上)上新增@Transactional,可以將整個類納入spring事務管理,在每個業務方法執行時都會開啟一個事務,不過這些事務採用相同的管理方式。

5、註解為事務範圍的方法中,事務的回滾僅僅對於unchecked的異常有效。對於checked異常無效。也就是說事務回滾僅僅發生在出現RuntimeException或Error的時候。

那麼什麼是checked異常,什麼是unchecked異常

java裡面將派生於Error或者RuntimeException(比如空指標,1/0)的異常稱為unchecked異常,其他繼承自java.lang.Exception得異常統稱為Checked Exception,如IOException、TimeoutException等

辣麼再通俗一點:你寫程式碼出現的空指標等異常,會被回滾,檔案讀寫,網路出問題,spring就沒法回滾了

解決方案一:手動回滾。給註解加上引數如:@Transactional(rollbackFor=Exception.class)

解決方案二:如上述分析。MyException改為繼承RuntimeException的異常。並且在service上層要繼續捕獲這個異常並處理

解決方案三:在service層方法的catch語句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();語句,手動回滾,這樣上層就無需去處理異常

6、如果希望一般的異常也能觸發事務回滾,需要在註解了@Transactional的方法上,將@Transactional回滾引數設為:

@Transactional(rollbackFor=Exception.class)