業務場景:用戶點擊購買後,修改訂單狀態,修改用戶賬戶餘額,並添加用戶消費記錄。
分析:這裏在同一個事務裏有三個動作,兩個是更新,一個是添加。如果這時候在更新完出現併發情況,那麼用戶消費記錄可能會多出一條,用戶賬戶餘額也可能出現錯誤。那麼該如何防止呢?在修改前查詢訂單狀態判斷是否已經修改過明顯不能解決問題,因爲併發可能發生在查詢之後。
解決思路:數據庫一般默認update操作會佔有一個行級鎖,當第一次請求的事務還未結束時,第二次重複請求是無法修改這條記錄的。我們讓修改操作都加上一個修改前的條件判斷,這樣第二次請求再來修改的時候會發現修改不成功,這時回滾事務即可避免併發。
解決辦法:在修改訂單時增加一個判斷(判斷其應該是未支付的訂單),然後返回更新的記錄條數,如果爲0則拋出異常,回滾當前事務。
sql語句如下:
update order set status = 1 where oid = 1 and status = 0;
在mybatis中可以獲取記錄更新的條數
int update(Map map);