悲觀併發控制(又名「悲觀鎖」,pessimistic concurrency control,縮寫「pcc」)是一種併發控制的方法。它可以阻止乙個事務以影響其他使用者的方式來修改資料。如果乙個事務執行的操作讀某行資料應用了鎖,那只有當這個事務把鎖釋放,其他事務才能夠執行與該鎖衝突的操作。
悲觀併發控制主要用於資料爭用激烈的環境,以及發生併發衝突時使用鎖保護資料的成本要低於回滾事務的成本的環境中。簡而言之,悲觀鎖主要用於保護資料的完整性。當多個事務併發執行時,某個事務對資料應用了鎖,則其他事務只能等該事務執行完了,才能進行對該資料進行修改操作。
update goods set num = num - 1 where id = 1001 and num > 0
假設現在商品只剩下一件了,此時資料庫中num = 1;但有100個執行緒同時讀取到了這個num = 1,所以100個執行緒都開始減庫存了。
但你會最終會發覺,其實只有乙個執行緒減庫存成功,其他99個執行緒全部失敗。
需要注意的是,for update
生效需要同時滿足兩個條件時才生效:
悲觀鎖採用的是「先獲取鎖再訪問」的策略,來保障資料的安全。但是加鎖策略,依賴資料庫實現,會增加資料庫的負擔,且會增加死鎖的發生機率。此外,對於不會發生變化的唯讀資料,加鎖只會增加額外不必要的負擔。在實際的實踐中,對於併發很高的場景並不會使用悲觀鎖,因為當乙個事務鎖住了資料,那麼其他事務都會發生阻塞,會導致大量的事務發生積壓拖垮整個系統。
select version from goods where id= 1001
update goods set num = num - 1, version = version + 1 where id= 1001 and num > 0 and version = @version(上面查到的version);
這種方式採用了版本號的方式,其實也就是cas的原理。
假設此時version = 100, num = 1; 100個執行緒進入到了這裡,同時他們select出來版本號都是version = 100。
然後直接update的時候,只有其中乙個先update了,同時更新了版本號。
那麼其他99個在更新的時候,會發覺version並不等於上次select的version,就說明version被其他執行緒修改過了。那麼我就放棄這次update
在秒殺的情況下,高頻率的去讀寫資料庫,會嚴重造成效能問題。所以必須借助其他服務, 利用redis的單執行緒預減庫存。比如商品有100件。那麼我在redis儲存乙個k,v。例如
每乙個使用者執行緒進來,key值就減1,等減到0的時候,全部拒絕剩下的請求。
那麼也就是只有100個執行緒會進入到後續操作。所以一定不會出現超賣的現象。
$expire = 10;//有效期10秒
$key = 'lock';//key
$value = time() + $expire;//鎖的值 = unix時間戳 + 鎖的有效期
$lock = $redis->setnx($key, $value);
//判斷是否上鎖成功,成功則執行下步操作
if(!empty($lock))
第四種方法,可以參考本書的這個章節:redis實現分布式鎖 測試面試,面試官問如何測試電梯
面試官問你 怎麼測試電梯 回答思路 以電梯為例 1 那麼首先,你要反問面試官,需求是什麼樣的,比如測什麼樣的電梯,是普通電梯,觀光電梯,還是其他 2 如果回答沒有,那麼你的思路應該就是 沒有需求文件,但我了解電梯的基本業務功能,以此依據,從下面幾個方面進行分析 功能測試 單個功能,邏輯業務 功能互動...
面試者如何回應面試官問的 你有哪些要問我的?
在面試快結束的時候你是否會經常被面試官問到 你還有什麼問題想要問我的嗎?你會不會很迷茫無措,不知道自己該問點什麼?如果你回到 我沒有問題了。這往往被一些面試官理解為 你對應聘公司 工作崗位沒有太大的興趣。可能會讓面試官產生誤解,從而影響面試評判。而自己呢,後面還會後悔自己當初沒有問到自己想要知道的內...
面試官都在問 如何檢視網路 程序資訊
各個大廠對於 linux 的考察中,命令是常見考點.命令中關於程序 網路資訊的檢視又是重中之重.同時這些命令也是實際工作中的常用命令.需要重點掌握.使用 netstat 命令檢視網路連線情況 netstat anp執行結果如下 引數解釋 a 顯示所有選項 t tcp 僅顯示tcp相關選項 u udp...