怎麼導致超賣?
多個用戶同時購買同一件商品(相同sku),產生高併發多線程。如果商品的個數僅有1個,A線程獲取到結果時因爲剩餘數量大於0,生成訂單、用戶付款。此時若在A線程生成訂單的途中,B線程獲取的商品剩餘數量是大於0的,也會生成訂單、用戶付款。導致結果只有一件商品賣了兩次,超賣了。
解決超賣:
- 用戶搶到商品,待付款
- redis分佈式鎖(根據商品的sku阻性)。獲得鎖代碼塊內,進行商品減數據數據庫樂觀鎖(庫中數量>購買數量)。
- 生成訂單信息。前提用戶商品數量更新成功。
- 保證兩步在一個事務中,同時成功和失敗,保證數據一致性(避免在生成訂單時失敗或者停機導致商品少賣)。
- 用戶付款
併發測試工具JMeter
QA:
爲什麼獲得分佈式鎖後,執行代碼中只有一條更新庫存語句
爲了減少鎖的持有時間,生成訂單和用戶付款都不會產生高併發,不用放在鎖中執行。
搶購人數超級多會直接撐爆Redis鎖隊列,怎麼處理?
請求限流,全局隊列異常IIIegaISlabEepeplian處理
如何保證用戶公平(按照順序)購買?
多線程在獲取不到分佈式鎖的時候,會將當前線程添加到隊列中,採用先進先出的模式逐個獲得鎖,來確保用戶公平購買,不存在插隊的情況。
爲什麼要加鎖,採用單線程不就可以了嗎?
的確可以解決商品超賣。但高併發的業務系統的響應速度非常慢。
用戶誰先付款成功,商品賣給誰,好實現嗎?
這個不行,因爲支付走的第三方,用戶同時付款機率非常大,超賣的機率也隨之增加了。有實現的方式歡迎補充下。