秒杀场景中,避免出现负库存,有很多种实现方法。这是网上常常提到的其中一种,就是利用redis 执行lua脚本的原子性来实现。
定义一个库存结构如下,total表示对应产品的库存总量,sell表示已销售的数量:
使用下面命令初始化库存:
hmset "stock:{101}" total 200 sell 0
写个LUA脚本,入参: key(产品) num(购买数量),返回:0 表示购买失败,大于0则成功
LUA脚本如下:
local ret = "0" ;
local num = tonumber(ARGV[1]) ;
local key = KEYS[1] ;
local stockInfo = redis.call("HMGET",key,"total","sell") ;
local total = tonumber(stockInfo[1]) ;
local sell = tonumber(stockInfo[2]) ;
if not total then
return ret ;
end ;
if total >= sell + num then
local ret = redis.call("HINCRBY",key,"sell",num) ;
return tostring(ret) ;
end ;
return ret;
使用EVAL执行LUA脚本