如何解決高並發下的超賣問題


1,超賣問題的話,我們一般是通過事務來解決,sql語句中直接將更新和查詢放在一起,通過行鎖

startTransaction();

try{

  int remainder = statement.query("select remainder from stock where stock_id='$STOCK_ID$'"; 得到此刻庫存

  然后根據訂單要求數量來進行比較,如果庫存大於等於訂單要求數量,就執行減坤村操作

}catch(Exception e){rollback();}

commit();   這個時候就出現超賣問題了,因為上面三個用戶同時搶購的時候,進入這個事務,然后同時執行update操作,

行鎖這個時候排他性,會將update操作串行化,所以最后就發生了超賣 就是上面是兩步操作,所以不可以

2,簡單的是將上面兩句語句合並為一句 update stock set remainder=remainder-amount where stock_id='$STOCK_ID$' and $remainder>=$amount 這樣就可以了

3,但是高並發下的情況又不一樣了 因為太多的update 都需要等待鎖,大量的請求超時

通過redis來減庫存 

  a,監聽相關物品的庫存信息,事務開啟前保證物品庫存不被修改

  b,獲取現有庫存信息,判斷滿足條件

  c,如果滿足就進行扣除操作

  d,如果第一步有人更新了物品庫存信息,進行重試

  e,如果庫存為0或者剩余庫存不滿足當前訂單扣除數量就退出。

秒殺服務的實際操作版本:

  用戶秒殺請求到達api網關,先到redis(沒有了就做一個標記)中判斷秒殺的商品是否庫存售罄,如果售罄直接返回秒殺失敗

  基於令牌桶算法的rateLimiter進行限流,得到令牌的請求才可以繼續進入到下面的邏輯

  要調用下游秒殺服務的接口,因為網關的並發處理能力大於下游的秒殺服務的處理能力,所以要通過排隊來限制涌入下游系統的流量,

  進入秒殺服務后,要考慮到分布式事務的問題,因為秒殺服務扣減庫存,然后訂單生成訂單和郵寄的相關信息,要保證信息的一致性,采用MQ,可靠消息最終一致性方案 MQ事務消息來實現。

  mq發送方在秒殺服務中,本地事務執行成功以后,也就是扣減秒殺庫存成功以后,就可以返回秒殺下單成功了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM