1.在今天測試代碼的正確性,遇到了事物不進行回滾操作.
例子:(僞代碼)
當第二個insert的時候,第一個方法沒有進行回滾.(查詢數據庫,數據表有產品信息)
2.查詢解答:
默認情況下spring事務只在發生未被捕獲的 RuntimeException時纔回滾(運行時異常)
try catch這種把整個包裹起來,這種業務方法也就等於脫離了spring事務的管理,因爲沒有任何異常會從業務方法中拋出,全被捕獲並“吞掉”,導致spring異常拋出觸發事務回滾策略失效。
3.最終解決方案:
解決方案1:
try {
spuDao.save(spuEntity);
skuDao.save(skuEntity);
} catch (Exception e) {
throw new RuntimeException();
}
解決方案2:
try {
spuDao.save(spuEntity);
skuDao.save(skuEntity);
} catch (Exception e) {
logger.info("保存接口出錯:"+e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
配置來捕獲特定的異常並回滾
(1)在service方法中不使用try catch,當代碼運行在第二句保存時,會拋出運行時異常,這時候就會進行回滾
(2)在catch中最後加上throw new RuntimeException(),這樣程序異常才能被aop捕獲進而回滾
解決方案:
方案1.例如service層處理事務,那麼service中的方法中不做異常捕獲,或者在catch語句中最後增加throw new RuntimeException()語句,以便讓aop捕獲異常再去回滾,並且在service上層(controller)要繼續捕獲這個異常並處理 (現在項目的做法)
方案2.在service層方法的catch語句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();語句,手動回滾,這樣上層就無需去處理異常