第43月第23天 商品秒殺 樂觀鎖

2022-06-23 09:57:09 字數 1095 閱讀 5838

1.

一般在**中,我們經常遇到某件商品只限10人搶購、秒殺

if($num > 0)

假設在乙個併發量較高的場景,資料庫中num的值為1時,可能同時會有多個程序讀取到num為1,程式判斷符合條件,搶購成功,num減一。這樣會導致商品超發的情況,本來只有10件可以搶購的商品,可能會有超過10個人搶到,此時num在搶購完成之後為負值。

我們該怎麼解決呢?

這裡我們可以有兩種方案,基於mysql和redis的方案。

基於mysql(悲觀鎖和樂觀鎖)

1、悲觀鎖

悲觀鎖的方案採用的是排他讀,也就是同時只能有乙個程序讀取到num的值。事務在提交或回滾之後,鎖會釋放,其他的程序才能讀取(select … for update)

2、樂觀鎖

樂觀鎖的方案在讀取資料是並沒有加排他鎖,而是通過乙個每次更新都會自增的version欄位來解決,多個程序讀取到相同num,然後都能更新成功的問題。在每個程序讀取num的同時,也讀取version的值,並且在更新num的同時也更新version,並在更新時加上對version的等值判斷。假設有10個程序都讀取到了num的值為1,version值為9,則這10個程序執行的更新語句都是update goods set num=num-1,version=version+1 where version=9,然而當其中乙個程序執行成功之後,資料庫中version的值就會變為10,剩餘的9個程序都不會執行成功,這樣保證了商品不會超發,num的值不會小於0,但這也導致了乙個問題,那就是發出搶購請求較早的使用者可能搶不到,反而被後來的請求搶到了。

基於redis解決方案

1、基於watch的樂觀鎖方案

watch用於監視乙個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。這種方案跟mysql中的樂觀鎖方案類似,具體表現也是一樣的。

2、基於list的佇列方案

基於佇列的方案利用了redis出隊操作的原子性,搶購開始之前首先將商品編號放入響應的佇列中,在搶購時依次從佇列中彈出操作,這樣可以保證每個商品只能被乙個程序獲取並操作,不存在超發的情況。該方案的優點是理解和實現起來都比較簡單,缺點是當商品數量較多是,需要將大量的資料存入到佇列中,並且不同的商品需要存入到不同的訊息佇列中

第43天 事件物件event

一 事件物件 事件 onmouseover onmouseout onclick event 事件的物件 相容寫法 var event event window.event event常見屬性,如下表 屬性 作用 data 返回拖拽物件的url 字串 dragdrop width 該視窗或框架的高度...

第44月第19天 SDK license

1.需要提供的引數 ios 應用bundleid android 包名和簽名資訊 md5 格式小寫無冒號 2.預燒錄預登記動態註冊預燒錄,指的是,我們後台預先生成授權的license檔案,然後預先寫入硬體裝置的儲存檔案中。在裝置首次啟動的時候,就直接調取license檔案進行啟用。這種方式適用於需要...

第28月第11天 vim b

1.首先以二進位制方式編輯這個檔案 vim b datafile 現在用 xxd 把這個檔案轉換成十六進製制 xxd 文字看起來像這樣 0000000 1f8b 0808 39d7 173b 0203 7474 002b 4e49 9.tt.ni 0000010 4b2c 8660 eb9c eca...