悲觀鎖與樂觀鎖是兩種常見的資源並發鎖設計思路,也是並發編程中一個非常基礎的概念。
悲觀鎖(Pessimistic Lock)
悲觀鎖的特點是先獲取鎖,再進行業務操作,即“悲觀”的認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業務操作。通常所說的“一鎖二查三更新”即指的是使用悲觀鎖。通常來講在數據庫上的悲觀鎖需要數據庫本身提供支持,即通過常用的select … for update操作來實現悲觀鎖。當數據庫執行select for update時會獲取被select中的數據行的行鎖,因此其他並發執行的select for update如果試圖選中同一行則會發生排斥(需要等待行鎖被釋放),因此達到鎖的效果。select for update獲取的行鎖會在當前事務結束時自動釋放,因此必須在事務中使用。
這里需要注意的一點是不同的數據庫對select for update的實現和支持都是有所區別的,例如oracle支持select for update no wait,表示如果拿不到鎖立刻報錯,而不是等待,mysql就沒有no wait這個選項。另外mysql還有個問題是select for update語句執行中所有掃描過的行都會被鎖上,這一點很容易造成問題。因此如果在mysql中用悲觀鎖務必要確定走了索引,而不是全表掃描。
使用例子
1.悲觀鎖需要等待提交commit后才可以執行
set autocommit = 0;
BEGIN;
SELECT * FROM `fook_business` where id = 1 FOR UPDATE;
UPDATE `fook_business` set `areas_id` = 2 where id = 1;
2.然後手動更新 id=1 這條數據,看到更新失敗,因為 id=1 這條被鎖住了
UPDATE `fook_business` set `areas_id` = 3 where id = 1;
3.commit提交成功
更新庫存時,用mysql鎖解決高並發問題的:https://mp.weixin.qq.com/s/gM_YT669SjJycflXTb_eBQ