添加數據庫行鎖
當請求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 冪等
不冪等的情況下 如果發生重複執行的額情況將產生重複扣款