購物併發之商品庫存

2021-07-25 12:33:11 字數 1595 閱讀 5297

購物**的併發,這個問題也算是老生常談的,很多大的電商**都對這塊的技術和業務,有了非常縝密的安排和設計。但是實際上在一些

小型的系統中,對於這塊內容的處理往往是缺乏規劃和經驗的。

最近也是在專案的測試中出現了商品庫存的問題,因此通過review**,也發現了商品訂單及支付這一塊對併發購買的處理是存在問題的。

商品庫存,作為購物流程中修改的最頻繁的資料,無疑是值得重視的。

在這個問題提出的同時,根據我的一些經驗,我也同時大致想到了幾種看似能夠解決問題的手段:資料庫鎖、快取及業務手段。

關於快取,本專案用的memcached,memcached比起redis,資料型別比較單一,序列化不方便,優點是讀取效率高一些,實際上解決業

務問題的能力上還是不如redis的。

對於資料庫的鎖,在**日常的執行過程中,使用資料庫鎖完全可以解決庫存超賣的問題,但是我相信稍大一些的系統都是不會這麼做的。

因為對於電商**常用的innodb來說,表級鎖開銷小,加鎖快,不會出現死鎖,發生鎖衝突的概率最高,併發度最低;行級鎖開銷大,加鎖慢,

會出現死鎖,鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。庫存問題如果使用資料庫的行級鎖解決,就很難避免死鎖的問題,更別提

**搞些活動,一些請求高峰的時段如此頻繁的鎖操作會對系統的體驗造成怎樣的影響了。

關於業務手段,實際上,專案中也是用到了這種手段:在下單時就修改商品庫存,在支付時再次比對庫存,一旦這樣做了,也有一些缺點,

比如惡意下單的問題————一些人下完單不買,耗光庫存,商品賣不出去。另外乙個問題就是,兩個人都下單成功,支付的時候都不能買,而

實際上第乙個人在下單的時候庫存確確實實是存在的,但他卻仍然無法購買商品,這就造成了最後幾件商品可能無法被利用的情況,造成了資源浪費。

基於以上幾種考慮,我綜合給出了這樣兩種搭配使用的方案:

首先,下單減庫存,存在一些缺點,但也有好處,那我們是不是可以給庫存設定乙個閾值呢?

因此我的方案是:預設情況下,當庫存大於閾值時採用支付減庫存的方式,當庫存小於閾值的時候採用下單減庫存的方式。同時,商家也可以自

己設定究竟使用哪種減庫存的方案。

另外,對於快取的應用,我的方案是記憶體鎖:當某個使用者修改某個id的商品庫存時,將商品id存放到memcached中,若其他使用者要對商品庫存進

行操作時,如果讀到memcached有這個id值,就阻止這個使用者,而之前的使用者操作完畢後,刪除memcached中的資料。這個思路其實本質上和悲觀

鎖是一致的!但是memcached的操作速度遠遠大於結構化資料庫,而且是專案架構現成的技術。

以上就是我參考的不少資料和朋友的想法,提出的解決方案。

寫了這麼多,在這個問題上總算也有了乙個交代,但是如果把這些粗淺的想法放到類似於**那樣的大併發**上去的話,無疑會有更多的問題

出現。但之前我也向一位技術總監級別的大牛請教過類似的問題,用他的話來說,**的庫存都是存在預留的,不會說倉庫裡10件商品,就在庫存中

填10。

因此,不是所有問題都是能用技術解決的,而我們只能盡量做到最好,這句話,每個做技術的人都應該銘記於心。

redis快取商品庫存減壓

redis預減庫存 主要思路減少對資料庫的訪問,之前的減庫存,直接訪問資料庫,讀取庫存,當高併發請求到來的時候,大量的讀取資料有可能會導致資料庫的崩潰。我們主要是通過這幾點來實現的 1 系統初始化的時候,將商品庫存載入到redis 快取中儲存,並不是需要先請求一次才能快取 2 收到請求的時候,現在r...

購物愉快(商品總數)

題目描述 某商店有a b c三款不同的商品。由於供貨原因,商家針對這三款商品推出了一種購買規則 購買b商品的數量要比a商品的數量多1個 購買c商品的數量要比b商品的數量多1個。現在告訴你商店內a b c三種商品各自的數量,請你根據購買規則計算出能購買商品的最大總數量。輸入 三個整數,分別代表商店中商...

併發減庫存 redis vs mysql

業務 商品有庫存,如10000 每買乙個商品 庫存就減一 減庫存可以通過mysql來實現 如 update product stock set stock stock 1 where product id 1 and stock 0 也可以使用redis來實現 如 decr 1 stock inte...