redis緩存 - 秒殺庫存超賣

關聯鏈接 http://blog.shuxuemi.cn/web/index/detail/19

首先庫存信息使用redis存儲;在防併發操作時(秒殺減庫存),一般由於check和set操作不是原子操作,導致髒數據。 從redis2.6開始可以使用lua腳本的形式,配合redis的單進程單線程模型,完成check和set原子操作
function createOrder($product_id, $num, $opt = [])
{
    //根據商品id生成具體的key,key中存的是商品的庫存數量
    $product_key = "product_stock_num:" . $product_id;
    $script = <<<PRODUCT_SCRIPT
local key = ARGV[1]
local num = ARGV[2]
local current_stock = redis.call('get', key)
if (current_stock >= num ) then
    local new_stock = current_stock - num
    redis.call('set', key, new_stock)
    return new_stock
else
    return -1
end
PRODUCT_SCRIPT;
    $redis = new \Redis();
    $redis->connect("127.0.0.1");
    $script_hash = $redis->script("load", $script);
    //當腳本執行失敗會返回false,失敗原因一般爲key不存在
    $flag = $redis->evalSha($script_hash, [$product_key, $num], 0);
    if ($flag !== false && $flag !== -1) {
        return true;
    }
    return false;
}
createOrder(1, 1);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章