電商防止庫存超賣解決方案

2021-09-27 02:38:20 字數 1275 閱讀 8231

悲觀鎖,也就是在修改資料的時候,採用鎖定狀態,排斥外部請求的修改。遇到加鎖的狀態,就必須等待。可以採用redis佇列+mysql事務控制的方案,下面是流程圖:

mysql的執行**:

begintranse(開啟事務)

try}catch($e exception)

commit(提交事務)

先執行update鎖住本條記錄,這樣就能保證其他執行緒執行不了更新操作,可以避免超扣現象。

上述的方案的確解決了執行緒安全的問題,但是,別忘記,我們的場景是「高併發」。也就是說,會很多這樣的修改請求,每個請求都需要等待「鎖」,某些執行緒可能永遠都沒有機會搶到這個「鎖」,這種請求就會死在那裡。針對這個問題我們稍微修改一下上面的場景,我們直接將請求放入佇列中的,採用fifo(first input first output,先進先出),這樣的話,我們就不會導致某些請求永遠獲取不到鎖。下面是整個執行流程圖:

悲觀鎖的解決方案解決了鎖的問題,全部請求採用「先進先出」的佇列方式來處理。那麼新的問題來了,高併發的場景下,因為請求很多,系統處理佇列內請求的速度根本無法和瘋狂湧入佇列中的數目相比,很可能一瞬間將佇列記憶體「撐爆」,最終web系統平均響應時候還是會大幅下降,系統還是陷入異常。

這個時候,我們就可以討論一下「樂觀鎖」的思路了。樂觀鎖,是相對於「悲觀鎖」採用更為寬鬆的加鎖機制,大都是採用帶版本號(version)更新。實現就是,這個資料所有請求都有資格去修改,但會獲得乙個該資料的版本號,只有版本號符合的才能更新成功,其他的返回搶購失敗。這樣的話,我們就不需要考慮佇列的問題,不過,它會增大cpu的計算開銷。但是,綜合來說,這是乙個比較好的解決方案。

樂觀鎖的執行流程如下:

有很多軟體和服務都「樂觀鎖」功能的支援,例如redis中的watch就是其中之一。通過這個實現,我們保證了資料的安全。

下面是利用redis中的watch實現樂觀鎖的**

while (true) 

} else

} catch (exception e) finally

}

庫存超賣的解決方案

update sku info set kc kc 1 where sku id and kc 0 在高併發下,多人搶同一庫存,由於資料庫讀寫可以並行執行的原因,會導致修改庫存時,庫存不足出現超賣。悲觀鎖解決 在select加乙個行鎖,與更新庫存操作互斥,保證查詢庫存時,庫存不被修改 在查詢和更新庫...

高併發下防止庫存超賣的解決方案

最近在看秒殺相關的專案,針對防止庫存超賣的問題,查閱了很多資料,其解決方案可以分為悲觀鎖 樂觀鎖 分布式鎖 redis原子操作 佇列序列化等等,這裡進行淺顯的記錄總結。首先我們來看下庫存超賣問題是怎樣產生的 1 2 3 45 6 1.查詢出商品 庫存資訊 select stock from t go...

電商 如何防止商品超賣

怎麼導致超賣?多個使用者同時購買同一件商品 相同sku 產生高併發多執行緒。如果商品的個數僅有1個,a執行緒獲取到結果時因為剩餘數量大於0,生成訂單 使用者付款。此時若在a執行緒生成訂單的途中,b執行緒獲取的商品剩餘數量是大於0的,也會生成訂單 使用者付款。導致結果只有一件商品賣了兩次,超賣了。解決...