原本的lua脚本代码

local voucherId = ARGV[1];
-- 用户id
local userId = ARGV[2];

-- 库存的key
local stockKey = 'seckill:stock:' .. voucherId;
-- 订单key
local orderKey = 'seckill:order:' .. voucherId;

-- 判断库存是否充足 get stockKey > 0 ?
local stock = redis.call('get', stockKey);
if (tonumber(stock) <= 0) then
    -- 库存不足,返回1
    return 1;
end

-- 库存充足,判断用户是否已经下过单 SISMEMBER orderKey userId
if (redis.call('SISMEMBER', orderKey, userId) == 1) then
    -- 用户已下单,返回2
    return 2;
end

-- 库存充足,没有下过单,扣库存、下单
redis.call('INCRBY', stockKey, -1);
redis.call('SADD', orderKey, userId);
-- 返回0,标识下单成功
return 0;

报错信息如下

大意就是尝试将一个nil值(也就是null)值转换为number类型

java.lang.RuntimeException: org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR Error running script (call to f_6fa1d26eca287ca8965281a18e0490c602207113): @user_script:24: user_script:24: attempt to compare nil with number ‘

local stock = redis.call('get', stockKey);
if (tonumber(stock) <= 0) then
    -- 库存不足,返回1
    return 1;
end

问题出在第二行的判断库存是否数量小于等于0,但是其实是可以注意到的stockKey之前是根本没有存进redis中

解决方法

添加判断即可防止nil报错,先判断是不是nil值

-- 判断库存是否充足 get stockKey > 0 ?
local stock = redis.call('get', stockKey);
if not stock then
    return 1; -- 库存不足
end
if tonumber(stock) <= 0 then
    return 1;
end

Logo

更多推荐