高併發下餘額扣減

添加數據庫行鎖

當請求A執行是 先加入鎖阻塞 請求B直到 請求A完成之後 請求B才繼續執行

//開始事務
begin;
//消費金額
$spend = 10;
//查詢用戶餘額
$user = select id,fee from users where id = 12 for update;
//計算金額
$newFee = $user['fee'] - $spend;

//...檢查餘額是否足夠
//更新餘額
update users set fee = $newFee where id = 12;
//確認成功之後,提交事務
commit

CAS業務層面樂觀鎖

什麼是CAS

在更新的時候使用初始值(即查詢出來的當前餘額)作爲條件compare限制只有初始值沒有改變時才允許更新成功set

Compare And Set(CAS)

//消費金額
$spend = 10;
//查詢用戶餘額
$user = select id,fee from users where id =12;
$oldFee = $user['fee'];
//計算金額
$newFee = $user['fee'] - $spend;
//...檢查餘額是否足夠
//更新餘額
update users set fee = $newFee where id = 12 and fee = $oldFee ;

爲什麼不使用減等於的SQL語句

例如:

update users set fee = fee - $spend where id = 12;

這裏要再加上餘額的判斷避免出現負數金額

update users set fee = fee - $spend where id = 12 and fee >= $spend;

稍微改一下這裏的更新 語句 也能完成正確的更新 就算是併發也將正常

但是這樣做將產生一個問題 不冪等?

什麼是不冪等?

在相同的條件下,執行同一請求,得到的結果相同才符合冪等性

也就是說

fee = fee - $spend 不冪等

fee = $newFee       冪等

不冪等的情況下 如果發生重複執行的額情況將產生重複扣款

發佈了70 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章