Transaction之坑:分析sql執行結果,主動促使事務rollback
阿新 • • 發佈:2019-02-15
場景
JavaWeb
開發,在開啟事務的Service層方法中,編寫業務邏輯時,經常會使用到如下兩種方式:
- 手動丟擲異常(如果你沒有配置
一般異常事務回滾
,請丟擲RuntimeEception
)
int resultInt = merchantCollectMoneyMapper.updateMerchantBalance(pmsAppTransInfo);
if(resultInt != 1){
logger.info("更新商戶賬戶餘額失敗,商戶ID:"+mercid +",結束時間:"+ UtilDate.getDateFormatter()+"。更新金額:"+ pmsAppTransInfo.getOrderamount());
throw new RuntimeException("手動丟擲");
}else{
//修改流水錶狀態
}
- 使用
TransactionAspectSupport
程式設計式實現手動回滾
int resultInt = merchantCollectMoneyMapper.updateMerchantBalance(pmsAppTransInfo);
if(resultInt != 1){
logger.info("更新商戶賬戶餘額失敗,商戶ID:"+mercid +",結束時間:"+ UtilDate.getDateFormatter()+"。更新金額:"+ pmsAppTransInfo.getOrderamount());
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}else {
//修改流水錶狀態
}
Summary:上述兩種方式都是通過對
Dao|Mapper
執行結果分析,決定transaction
是否rollback
。
問題
- 不是說
TransactionManager
會根據service層方法throws
的Exception
來自動
決定transaction
回滾嗎? - 那麼還有必要分析SQL語句的執行結果嗎?
- 執行失敗肯定會丟擲異常,然後自動回滾的吧?
解決
- 圖1:一個
資料為空
的表
- 圖2:使用
不存在的主鍵
執行update
操作
console:受影響的行:0
- 表明:
- 儘管SQL操作的資料行不存在,並不會有
Exception
summary:受影響的行為
0
,同樣意味著業務邏輯執行失敗
,而且此時並不會產生Exception
,Transaction
仍會被commit
,如果這個方法包含一系列 write 操作
,自然會產生髒資料
。顯然這不是我們所期望的,所以,在這種情況下,我們需要分析SQL執行後的結果,來決定是否應該主動
促使事務rollback
。