分布式锁 Lua脚本 (四)
前三章 介绍了 阻塞锁 乐观锁 redlock ,现在介绍 用Lua脚本的方式 ,这种方式并不是锁 ,他避开了 锁的应用 利用了 redis的 单线程 原子性的 特性完美规避了锁的使用也规避了
计算 业务时间和 锁过期时间和等待时间 ,所以 遇到 使用 分布式锁的情况 应该首选Lua脚本的方式
Lua 脚本的教程 Lua 文件 I/O | 菜鸟教程 (runoob.com)
测试

上代码
public class LuaTest
{
public static readonly string LuaTotal = "luatotal";
public static void Test()
{
using (RedisClient redisClient = new RedisClient("192.168.0.168:6379"))
{
string lua = @"
if redis.call('EXISTS',KEYS[1])==1 then
local total = redis.call('GET',KEYS[1]);
if tonumber(total)<=0 then return -2 end;
return redis.call('DECR',KEYS[1]);
else return -1 end;";
string result = redisClient.ExecLuaAsString(lua, new string[] { LuaTest.LuaTotal }, null);
switch (result)
{
case "-1": Console.WriteLine($"报错 没有totalkey"); return;
case "-2": Console.WriteLine($"抢购活动已经结束,返回代码为{result}"); return;
default:
Console.WriteLine($"库存扣减成功,剩余库存为{result}");
break;
}
}
}
}
string lua = @" if redis.call('EXISTS',KEYS[1])==1 then local total = redis.call('GET',KEYS[1]); if tonumber(total)<=0 then return -2 end; return redis.call('DECR',KEYS[1]); else return -1 end;";
上面是核心代码
首先判断 key 是否存在 redis.call('EXISTS',KEYS[1])==1 等于1为存在
local total = redis.call('GET',KEYS[1]) 获取总数
if tonumber(total)<=0 then return -2 end; // tonumber 将 total 字符串转换 数字 判断 是否 小于等于0
return redis.call('DECR',KEYS[1]); //扣减 返回 库存结果
总结 总体来说 不是很难 但是 要学习 Lua 脚本语法花点时间 还要属性 redis-cli 命令
浙公网安备 33010602011771号