跳轉到

庫存系統

記錄庫存餘額還是記錄售賣數量?

方案 1:記錄庫存餘額的方案是,每次購買時庫存餘額都會減去購買數量。一旦庫存餘額小於等於 0,則無法再減少庫存數量,商品則不可再售賣,直到庫存得到補充。範例 SQL 如下

update inventory set cnt = cnt - #{buyCnt} WHERE productId = #{productId} AND cnt - #{buyCnt} >= 0

方案 2:記錄販售數量的方案是,每次購買時,已售出數量+ 目前購買數量。加和以後,一旦已購買數量大於庫存總數時,則庫存不足,商品則不可再對外售賣,直至庫存得到補充。

update inventory set cnt = cnt + #{buyCnt} WHERE productId = #{productId} AND cnt + #{buyCnt} <= totalCnt

這兩個方案都可以實現庫存功能。但是庫存不足後,需要補充庫存的場景,兩個方案有差異,存在優劣。

例如目前總庫存為 100,已售出了 51 個,剩餘庫存為 49 個。依照方案 1(庫存餘額)的要求,當庫存從 100 增加到 200 時,除了庫存總數需要增加,剩餘庫存數量也需要增加 100 個,變成 149 個。

然而,減少庫存總數這一場景,方案 1 的實現方案更加複雜。當庫存從 100 減少到 50 時,由於庫存餘額為 49 個,庫存餘額減掉 50 後,則為-1。因為庫存餘額為負數屬於異常場景,所以需要將剩餘庫存設為 0。然而,這會引起數據的一致性問題。

因為庫存餘額不準確,所以已售數量 = 庫存總數 - 庫存餘額,這個等式也不再正確,如果商品需要展示已售数量,使用這個公式就無法保證已售出數量的準確性。

在方案 1 中,每次調整庫存總數都需要調整庫存餘額,增加了操作複雜度。因為 C 端交易流程需要操作庫存餘額,B 端調整庫存總數也會涉及調整庫存餘額,BC 端的庫存作業需要互斥,否則會出現資料不一致的問題。

相較之下,方案 2(記錄售賣數量)則沒有方案 1 的困境。增加或減少庫存總數只需要調整相應的庫存總數。目前售賣數量只有 C 端交易流程會修改,庫存總數只有 B 端庫存管理場景會修改。查詢商品的已售賣數量只需要查庫存的已售數量即可,而商品的庫存餘額可以透過庫存總數減去已售數量得到。庫存餘額 = 庫存總數 - 已售數量 ,BC 端的操作不會影響這個等式的正確性。

綜上所述,方案 1 使用庫存餘額更加複雜,且沒有明顯的收益。而方案 2 記錄販售數量的方案更簡單,調整庫存更簡潔優雅,不會有資料一致性問題。透過記錄售賣數量,很容易就可以知道當前商品的已售賣數量。

下單扣減庫存還是支付扣減庫存?

下單扣庫存

下單前扣減庫存,當訂單取消和退款時回補庫存。這個方案可以確保用戶下單成功就一定能購買成功,下單階段就佔用庫存的壞處是,如果大量用戶虛假下單,但是不支付訂單,就會有大量庫存被佔用,影響正常用戶下單。

支付前扣庫存

為了避免下單扣庫存帶來的問題,可以引入了一個新的方案:支付前扣減庫存,當訂單退款時,回補庫存。這樣,用戶下單時不再佔用庫存,避免了大量庫存被佔用但未支付的情況。

然而,這種方案也存在一些問題。如果用戶下單成功後在付款時庫存不足,系統會向其提示"庫存已售罄",這對用戶體驗造成了極大的影響。

我曾經在京東搶茅台的過程中遇到過這個問題,我認為只要下單成功,就應該能購買到商品,但在支付時被告知庫存不足,我感覺自己被耍了,我非常氣憤,從此以後我就再也不參與這個平台的秒殺搶購了。(後來也不用京東了,基本上只用拼多多了)。

最好使用下單扣減庫存

以上兩個方案各有優劣,因為方案 2(支付扣庫存)的使用者體驗太差。所以盡量避免使用方案 2(支付扣庫存),優先使用方案 1(下單扣庫存)。

對於方案 1(下單扣庫存)的弊端,也有解決方法。

通常情況下,業界會限制訂單支付時長,要求用戶在 15-30 分鐘內完成支付,以避免訂單長時間處於待支付狀態。如果訂單未在規定時間內支付,訂單會被取消,庫存也會被還原,因此不會一直佔用庫存的情況發生。

大量正常用戶下單後不支付而導致訂單取消率過高,顯示系統有問題阻礙用戶支付。這種情況下,大量佔用庫存屬於異常場景,可以忽略不計。

只有黑產用戶才會故意使用大量帳號佔用庫存,以影響販賣。然而仔細思考一下,佔用庫存、影響販賣對黑產並沒有好處。所以實際發生的機率非常低。只需要讓訂單提單接口接入風控,風控接口識別並封鎖黑產用戶,讓風控團隊和黑產鬥智鬥勇就能解決方案 1(下單扣庫存)的弊端。

在系統設計時,我們必須進行正確的權衡。方案 1 的缺陷是:容易受到黑產用戶的攻擊,但黑產動力有限,機率較低。方案 2 的缺陷是:使用者體驗極差,可能導致使用者流失。

兩害相權取其輕,我認為使用者體驗更為重要,應該選擇方案 1(下單扣庫存)。這也是和大多數公司的選擇相同。

Reference