1. 程式人生 > >Transaction之坑:分析sql執行結果,主動促使事務rollback

Transaction之坑:分析sql執行結果,主動促使事務rollback

場景

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層方法throwsException自動 決定transaction回滾嗎?
  • 那麼還有必要分析SQL語句的執行結果嗎?
    • 執行失敗肯定會丟擲異常,然後自動回滾的吧?

解決

  • 圖1:一個 資料為空 的表
    這裡寫圖片描述
  • 圖2:使用不存在的主鍵執行 update 操作
    這裡寫圖片描述

console:受影響的行:0

表明:
儘管SQL操作的資料行不存在,並不會有 Exception
丟擲,結果僅僅是: results=0

summary:受影響的行為 0,同樣意味著 業務邏輯執行失敗,而且此時並不會產生 ExceptionTransaction 仍會被 commit,如果這個方法包含 一系列 write 操作,自然會產生 髒資料。顯然這不是我們所期望的,所以,在這種情況下,我們需要分析SQL執行後的結果,來決定是否應該 主動 促使事務 rollback