文章目錄
- 業務背景
- 分布式事務解決方案及缺點
- 業務程序分析
- 下單扣減庫存的業務難點
- 解決方案
- 1. 先扣庫存,后創建訂單
- 2. 先創建訂單,后扣庫存
- 例外資料處理
- 1. 庫存表流水表
- 2. 重試+回滾+報警+人工介入
- 總結
這里是weihubeats,覺得文章不錯可以關注公眾號小奏技術,文章首發,拒絕營銷號,拒絕標題黨
業務背景
我們這里將業務簡化為最簡單的下單扣庫存邏輯,不去關注其他分支部分來理解整個電商下單扣庫存的解決方案
分布式事務解決方案及缺點
- 最終一致性:異步解決方案,資料同步有延遲,性能高
- TCC(try、Confirm、Cancel):同步解決方案,正常需要兩個階段(try、Confirm),對性能損耗較大
- 事務狀態表:同步方案,但需要每次記事務流水表、更新事務狀態,比較繁瑣和TCC類似,性能也有較大消耗
- 異步對賬:也是一個異步程序,需要后臺定時器去對賬補全資料
這里就不詳細介紹每種解決方案的場景和使用了
業務程序分析
下單至少包含的兩種操作:
- 創建訂單
- 扣減庫存

這里的訂單和庫存之間的呼叫故意畫成雙向的,客戶端故意兩個服務都呼叫,后面會具體分析
下單扣減庫存的業務難點
- 需要同步執行,扣減庫存的結果需要立即知道,否則會發生超賣違約
- 需要很高的性能
可以看到需要同步執行,又要高性能,所以TCC和事物狀態表異步對賬這幾種方案就可以排除了,既要高性能又要強一致性,魚和熊掌本就不可兼得,但是我們基于業務本身去分析,會發現有一個很關鍵的特點
不允許超賣,但是允許少賣,就是我們可以多扣庫存不能少扣庫存,比如100件商品我們可以買出99件,有1件沒賣出去是可以接受的,但是如果100件商品賣給101人,其中有一個人收不到貨就可能造成平臺違規不能接受(具體業務場景具體分析,有些業務場景可能也能接受比如,故意超賣及時補貨等,但這里就以上面說的不允許超賣為業務前提),
解決方案
1. 先扣庫存,后創建訂單
會有如下三種情況發生
- 扣庫存成功,創建訂單成功,回傳結果成功
- 扣庫存成功,創建訂單失敗,回傳結果失敗,呼叫方重試(出現多扣減庫存,多創建訂單)
- 扣庫存失敗,不再創建訂單,回傳結果失敗,呼叫方重試
| 情況 | 扣庫存 | 創建訂單 | 回傳結果 | 影響 |
|---|---|---|---|---|
| 1 | 成功 | 成功 | 成功 | 無 |
| 2 | 成功 | 失敗 | 失敗 | 多扣庫存、多創建訂單 |
| 失敗 | 無 | 失敗 | 無 |
注意 扣庫存和創建訂單是不同的事務,不能放在通一個事務中,因為存在網路兩將軍問題
2. 先創建訂單,后扣庫存
也會有如下三種情況
- 創建訂單成功,扣減庫存成功,回傳結果成功
- 創建訂單成功,扣庫存失敗,呼叫方重試(可能出現多扣減庫存)
- 創建訂單失敗,不再扣庫存,回傳結果失敗,
| 情況 | 創建訂單 | 扣庫存 | 回傳結果 | 影響 |
|---|---|---|---|---|
| 1 | 成功 | 成功 | 成功 | 無 |
| 2 | 成功 | 失敗 | 失敗 | 多扣庫存,多創建訂單 |
| 3 | 失敗 | 無 | 失敗 | 無 |
這里情況2為什扣庫存失敗了還會存在多扣庫存的情況呢?因為這里的失敗分兩種,一種是庫存系統真的扣庫存失敗,第二種就是庫存扣成功了,可能因為網路原因導致訂單系統認為扣失敗了,詳細情況可以了解網路兩將軍問題
先創建訂單的方式可能出現訂單創建成功,然后庫存失敗,導致創建了訂單而庫存未扣減,所以這種方案并不合適,除非將扣減庫存和創建訂單放在一個事務中,那又變成了先扣減庫存,如果放在通一個事務,最壞的情況也是多扣減庫存
例外資料處理
可以看到兩種方案都會出現多扣減庫存,那么如何處理這些例外資料呢?
1. 庫存表流水表
- 在每次扣減庫存的時候都去生成一條庫存流水記錄表,狀態為占用,訂單支付成功后,將狀態改為釋放
- 定時庫存對賬去掃描那些長時間狀態為占用不釋放的庫存流水,根據訂單狀況看看是因為多扣的庫存還是未支付的庫存,然后將這些訂單取消
2. 重試+回滾+報警+人工介入
上面的解決方案還是需要去維護一個多的庫存流水表,然后去修改狀態,如果需要更為簡單使用的方案,就是通過重試+回滾+報警+人工介入,
基于方案 先扣庫存,后創建訂單,我們不作狀態補償,添加重試、報警、回滾、人工介入
具體流程

可以看到雖然最后還是要人工介入,但是很明顯這種方案是很實用的,
不過這種方案在非常極端的情況可能存在回滾庫存的時候系統宕機還是會多扣庫存,其次在第一次扣庫存存在多扣庫存也無感知,肯定需要添加一個扣庫存記錄表(如果有MQ就先發一條延時訊息),這里也就沒畫出來了,因為要注意細節太多了
可能上面的流程還涉及分布式鎖等各種其他操作,這里就不重點展開了,因為主要是分析分布式事務的一種解決方案
如果想要更為穩妥的實作方案,可以基于訊息中間件解決,比如RocketMQ的事務訊息,具體實作方式可以參考這里
[分布式事務之可靠訊息最終一致性RocketMQ實作落地]
https://blog.csdn.net/qq_42651904/article/details/121133057?spm=1001.2014.3001.5501
總結
總的來說分布式事務的解決方案有很多,每種解決方案都適用于不同的場景,大家在解決使用的時候還是需要結合業務來選擇具體的解決方案,沒有最好的方案,只有最適合的,
然后最重要的就是要記住所有的其他系統的呼叫都要有檢查回滾操作
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/420466.html
標籤:其他
上一篇:機器學習框架及評估指標詳解
