1. 程式人生 > 實用技巧 >秒殺搶購時的併發處理方案

秒殺搶購時的併發處理方案

類似商城的秒殺場景,大家肯定都遇到過。如何處理好秒殺時候商品的庫存限制問題,真的一直讓人頭大。

常見的處理方案不外乎下面兩種:

1、鎖

表鎖、行鎖、檔案鎖。將需要操作的商品資料鎖定,當前使用者購買成功後,釋放鎖,允許其他使用者操作該條資料。

2、佇列

將請求放入佇列中,也就是所有的請求都進行排隊等待,按照順序依次處理。併發請求都放到佇列中,由額外程序序列處理,併發問題就不存在了,但是要額外程序支援以及處理延遲嚴重。

以上兩種方案都避免不了“等待”的問題,高併發極端場景下,很可能會造成系統響應異常。暫時不對這兩種方案作詳解。

最近在學習 redis,發現可以結合 redis 的事物和 watch 命令巧妙解決超賣的問題。

老規矩,使用 watch 之前先來了解下它的特性。畢竟使用場景是以事物的特性為基礎的。

watch 命令可以監控一個或多個鍵,一旦其中一個鍵被修改或刪除,之後的事物就不會執行。監控一直持續到 exec 命令。

話不多說,直接上程式碼。

$redis = JRedis::getInstance();
$key = 'saleCount:id:3';

$redis->watch($key);
//銷量
$sales = $redis->get($key);
//庫存
$qty = 8;
if ($sales >= $qty) {
    exit("已售罄");
}
//開啟事務
$redis
->multi(); $redis->incrby($key, 1); $result = $redis->exec(); if ($result) { //執行資料庫的銷量增加操作,執行訂單建立等操作 exit("校驗成功,開始資料庫操作"); } else { $redis->incrby($key, -1); exit("重新下單"); }

親測效果槓槓的,而且就效率來說,要優於鎖和佇列。而且,還可以使用 redis 分攤資料庫的壓力,豈不是美滋滋。

5分推薦。

好文章分享:

https://zhuanlan.zhihu.com/p/269746986

https://zhuanlan.zhihu.com/p/336113193