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);

 

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