天天看點

庫存復原架構設計原則

1、在設計公司的庫存架構的時候,出現了問題,當處理無座商品的時候,發現,復原邏輯有問題,具體的邏輯為:

比如如果庫存設定為1 ,則 

(1) 使用者1 下單成功,庫存-1

(2)使用者2下單因為庫存 是0是以 下單失敗,開始復原,復原的時候+1,導緻目前的庫存為 1(實際上這個庫存已經被使用者1買走了)

(3)使用者3 下單成功 ,庫存-1

最後:導緻庫存1 賣了2次,

原因分析:

復原邏輯沒有顯示訂單号,應該嚴格按照訂單号復原,否則會把别人的庫存復原掉;

大麥的邏輯設定:

首先第一步:

假設庫存總量為total_count,本次使用者下單的數量為10;

資料庫有3列,總 total_count,已售: sale_count,剩餘 marging_count;

這些都放在一個事務中

try{

1、查詢訂單庫存,如果庫存不足直接傳回 查詢的條件唯一(比如按照訂單号)

2、将庫存鎖定比如 1是未鎖定,2是鎖定 則 設定目前的行為鎖定狀态;

update recrod set status=2 where status=1 and 條件;

3、如果需要修改的庫存有多條,對需要修改的庫存進行排序(防止死鎖)

4、逐行設定庫存:

update sale_count+10 ,margin_count-10  where 條件+status=2 and sale_count-10>=0; 

} catch(Exception e){

}

之是以如此設定:

1、全部放在一個事務中,友善異常復原,

2、使用一個status鎖定狀态,因為mysql是行鎖,保證事務并發處理的時候隻有個線程可以往後走,後面的線程會等待,處理一條資料,

3、指定一個唯一條件,比如按照訂單号復原,如果訂單号不滿足直接退出,防止復原别人的庫存

4、設定庫存的時候,需要先進行排序,讓線程順序執行,防止死鎖,舉個栗子:

如果不排序:A,B兩個線程 ,復原庫存 ,如果第一個A線程扣減了X1行,下一步執行Y1行,

但另一個線程B,扣減了Y1,下一步需要扣減X1行,這時候,

A線程占着X1行,需要等待B線程釋放Y1行,

而同時B線程占着Y1行,等待着A線程釋放X1行,

庫存復原架構設計原則

産生了死鎖

是以必須要排序;

5、扣減的時候執行 條件添加:sale_count-10>=0; 保證即使某個地方有問題,也不會扣減為負數; 

問題:1、sale_count-10>=0; 不是小于=0;

是的;

2、排序如何排序,根據什麼條件排序 根據票品的ID進行排序,保證順序;

3、我們的設定狀态是鎖定狀态?那也就是每個庫存都要設定一個是否鎖定的狀态? 還是專門設計一張表,鎖定狀态,賣座的優惠券發券如何設計

可以加一張新表把狀态放進來;