所謂庫存超賣是指在併發量大的情況下,賣出去的商品數量比實際庫存多,如秒殺系統
1、超賣舉例:
總庫存:4個商品 ; 請求人:a、1個商品 b、2個商品 c、3個商品
偽**:
select 庫存數量 from 庫存表 where 商品id=***;
if 庫存數量-扣減庫存數量
update 庫存表 set 庫存數量=庫存數量-扣減商品數量 where 商品id=***;
這種方法先檢視庫存,然後判斷有庫存就下單操作,看似沒有,仔細分析下
1. 兩個事務同時讀取同乙個商品,inndb對select語句不會加鎖,就算加共享鎖,其他事務也可以讀。所以3個事務得到的庫存都是4
2. 兩個事務同時修改操作,mysql會將併發update語句序列化處理,乙個乙個執行。這樣當第乙個update操作的時候會生成排他鎖,其他事務等待,當第乙個事務提交後,第二個事務得到鎖繼續update操作。那這樣的話庫存就為-1了。
3. 結論:高併發情況下會出現使用者a、b、c同時讀到庫存為4,然後序列成功執行了扣減庫存操作,這樣執行完後,庫存肯定為負數了。
2、資料庫行級鎖
優點:mysql的indb引擎的for update語句是行級資料鎖,定能防止併發。
缺點:資料庫併發效能本來一般就是系統的瓶頸,行級鎖會進一步降低資料庫併發效能,但是金融方面一般用這種行級鎖方案比較多,通過垂直和水平分庫來提公升資料庫的併發效能。
select 庫存數量 from 庫存表 where 商品id=*** for update;
update 庫存表 set 庫存數量=庫存數量-*** where 商品id=***;
3、資料庫樂觀鎖
優點:相比資料庫行級鎖效能更高
缺點:在關聯式資料庫中此種場景還是比較合適的,暫未發現缺點
偽**:
更新數量 = upddate 庫存表 set 庫存數量=庫存數量
4、**demon實現
說明:demon有1、多執行緒併發下出現超賣 2、資料庫行級鎖避免超賣 3、資料庫樂觀鎖避免超賣
5、參考文章
高併發下防止庫存超賣的解決方案
最近在看秒殺相關的專案,針對防止庫存超賣的問題,查閱了很多資料,其解決方案可以分為悲觀鎖 樂觀鎖 分布式鎖 redis原子操作 佇列序列化等等,這裡進行淺顯的記錄總結。首先我們來看下庫存超賣問題是怎樣產生的 1 2 3 45 6 1.查詢出商品 庫存資訊 select stock from t go...
高併發下的庫存扣減方案
那年還很low db 剛開始我們的營銷專案組身單力薄,人微言輕 那時營銷業務才剛開始發展,此時我們把業務放到第一位,技術方案為滿足時間內業務發展所讓步。大家應該可以猜到,這個時候我們很low的庫存扣減方案 直接上資料庫。根據業務訴求,每個活動會儲存乙份實時變化的庫存,參與活動時,實時扣減資料庫,操作...
《轉》 mysql處理高併發,防止庫存超賣
今天王總又給我們上了一課,其實mysql處理高併發,防止庫存超賣的問題,在去年的時候,王總已經提過 但是很可惜,即使當時大家都聽懂了,但是在現實開發中,還是沒這方面的意識。今天就我的一些理解,整理一下這個問題,並希望以後這樣的課程能多點。先來就庫存超賣的問題作描述 一般電子商務 都會遇到如 秒殺 之...