1. 程式人生 > >庫存扣多了,到底怎麼辦

庫存扣多了,到底怎麼辦

業務複雜、資料量大、併發量大的業務場景下,典型的網際網路架構,一般會分為這麼幾層:

呼叫層,一般是處於端上的瀏覽器或者App;
站點層,一般是拼裝html或者json返回的web-server層;
伺服器,一般是提供RPC呼叫介面的service層;
資料層,提供固化資料儲存的db

對於庫存業務,一般有個庫存服務(stock-service)提供庫存的查詢get stock、扣減reduce stock、設定set stock等RPC介面。

庫存查詢,stock-service本質上執行的是:

select num from stock where id=$id;

庫存扣減,stock-service本質上執行的是:

update stock set num = num - $reduce where id=$id;

庫存設定,stock-service本質上執行的是:

update stock set num = $new_num where id=$id;

使用者下單前,一般會對庫存進行查詢,有足夠的存量才允許扣減。

但是在併發量很大的情況下,會有問題:比如2個併發操作,查詢庫存,得到的值都是5。接下來使用者發生了併發的購買動作(秒殺類業務特別容易出現): 使用者1購買了3個,於是庫存修改為2; 使用者2購買了2個,於是庫存要修改為3。

這2個修改庫存的介面併發執行,庫存會先變成2,再變成3,導致資料不一致

,(實際賣出了5件商品,但是庫存只扣減了2)。

其根本原因是,修改庫存操作發生的時候,沒有檢查庫存和查詢出來的庫存有沒有變化。 升級庫存設定介面也很容易:

update stock set num = $new_new where id=$id and num = $old_num;

這就是大家常說的Compare And Set(CAS),是一種常見的降低讀寫鎖衝突、保證資料一致性的方法。