電商中的庫存管理實現 mysql與redis

2021-07-25 19:47:57 字數 2239 閱讀 4760

庫存是電商系統的核心環節,如何做到不少賣,不超賣是庫存關心的核心業務問題。業務量大時帶來的問題是如何更快速的處理庫存計算。

此處以最簡模式來討論庫存設計。

以下內容只做分析,不能直接套用,歡迎各位同道前來交流指正

庫存模型:sku,num。

sku是標示商品的唯一編號,num是商品的數量。

訂單處理時需扣減商品庫存。

庫存初始資料:

mysql隔離級別read-committed

扣減1001庫存7:

10-7=3;

3>0;

開始扣減庫存

updatestockset num=3 where sku=1001;

在序列執**況下以上邏輯是正確的處理方式。

如果是併發執行,可能會出現這種情況:

10-7=3;

庫存在另外乙個執行緒中被修改為5

updatestockset num=3 where sku=1001;

庫存最終被修改為3

一共賣出5+7=12個商品,實際總商品數是10,超賣發生。

為解決超賣引入如下方案:

10-7=3;

3>0;

開始扣減庫存

庫存在另外乙個執行緒中被修改為5

updatestockset num=num-7 where num>=7 and sku=1001;

update失敗,超賣解決。

考慮到訂單的商品有多個,那在併發執行的情況下是否還是正常呢?

現有訂單1,訂單2同時處理,都是1001扣減庫存5,1002扣減庫存10

訂單1:

updatestockset num=num-5 where num>=5 and sku=1001;

updatestockset num=num-10 where num>=10 and sku=1002;

訂單2:

updatestockset num=num-10 where num>=10 and sku=1002;

updatestockset num=num-5 where num>=5 and sku=1001;

若sql執**況是訂單1先修改1001,訂單2修改1002,這個時候產生死鎖,有乙個訂單必然會失敗。

少賣發生。

如果是訂單2中第二個商品是1003會怎麼樣呢?

兩個訂單的庫存修改會變成序列執行。

這種情況下會帶來效能下降的問題,事務超時的時候會發生多個訂單失敗的情況。

多個訂單失敗後如果訂單依然要處理,此時庫存沒有扣減,又會發生超賣

結論:mysql可以保證資料一致性和永續性,但是效能不高,在量級較高的情況下庫存並沒有控制好少賣超賣的情況。

mysql的缺點是如此顯而易見,為了解決這個問題,現在引入redis。

redis的讀寫速度快,資料操作都在記憶體中執行,效能必然比mysql高。

string型別提供了decrby方法,可以以原子方式對string做減法。

對1001庫存減5:

decrby 1001 5

獲得返回值,如果小於0則執行

incrby 1001 5

並且所有相關資料回滾

在多執行緒環境中會有多個訂單同時回滾,庫存充足的情況。產生這種現象後,失敗的訂單可以留待下次再行處理。

但是庫存的值並不能用來做實時計算,因為失敗訂單的庫存沒有進行計算。

redis沒有事務,無法保證資料一致性。

結論:redis解決了效能問題,但是資料一致性無法保證。

為解決mysql問題,可以結合非同步定時扣減庫存,佇列做。

最後,不管用mysql還是redis 都各有優缺點.

電商的庫存修改

悲觀鎖和樂觀鎖之樂觀鎖 修改記憶體的sql update eb sku t set t.stock inventory t.stock inventory where t.sku id 1020 and t.stock 模擬線程併發問題 加上and 可以減少資料並非的問題 判斷庫存是否足夠 例項1u...

電商系統 好用的電商系統 電商管理系統

好用的電商管理系統 首先對於日漸擴大的電商行業來說,每日訂單資料統計 訂單產品的分類 老客戶的維護 店鋪每日的實際收入 庫存情況 採購物品的資訊跟蹤都是需要我們花時間去統計和關注的,所以電商管理最主要的作用應該體現在 1.商品管理 2.庫存管理 3.採購管理 4.訂單管理 5.配送結算 6.財務管理...

電商系列 mysql高併發超庫存賣問題

先來就庫存超賣的問題作描述 一般電子商務 都會遇到如 秒殺 之類的活動,而這樣的活動有乙個共同的特點就是訪問量激增 上千甚至上萬人搶購乙個商品。然而,作為活動商品,庫存肯定是很有限的,如何控制庫存不讓出現超買,以防止造成不必要的損失是眾多電子商務 程式設計師頭疼的問題,這同時也是最基本的問題。從技術...