使用Redis Lua脚本实现秒杀扣库存

什么是Lua脚本

LUA脚本语言是C开发的,类似存储过程

使用Lua脚本的好处

1.减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行
2.原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令	插入。换句话说,编写脚本的过程中无需担心会出现竞态条件
3.复用性,客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑

C#代码

string script =
              "if (redis.call('exists', ARGV[1]) == 1) then"
            + "    local stock = tonumber(redis.call('get', ARGV[1]));"
            + "    local num = tonumber(ARGV[2]);"
            + "    if (num <= 0) then"
            + "        return -4;"
            + "    end;"
            + "    if (stock <= 0) then"
            + "        return -1;"
            + "    end;"
            + "    if (stock >= num) then"
            + "        local val = redis.call('incrBy', ARGV[1], 0 - num)"
            + "        if tonumber(val) >= 0  then"
            + "            return 1;"
            + "        else"
            + "            return -5;"
            + "        end;"
            + "    end;"
            + "    return -2;"
            + "end;"
            + "return -3;";

//5为扣减数量
var result = (await _cahce.EvalAsync(script, "", key, 5)).ToString()

//result返回值
//-5:库存操作失败 
//-4:代表库存传进来的值是负数(非法值) 
//-3:库存未初始化 
//-2:库存不足 (不够扣减)
//-1:库存为0