分布式锁 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 命令
 
 


  

 

posted on 2023-11-12 11:47  是水饺不是水饺  阅读(37)  评论(0)    收藏  举报

导航