Redis 分布式锁混淆结果与 Lua 脚本

Posted

技术标签:

【中文标题】Redis 分布式锁混淆结果与 Lua 脚本【英文标题】:A Redis distributed lock confusing result with Lua script 【发布时间】:2018-11-20 06:06:09 【问题描述】:

我用这样的代码来实现Redis分布式锁:

DefaultRedisScript<String> script = new DefaultRedisScript<>();
script.setScriptText("if not redis.call('get', KEYS[1]) then return redis.call('set', KEYS[1], ARGV[1],'ex',ARGV[2],'nx') else return false end");
String result = redisTemplate.execute(script,
            Collections.singletonList("REDIS_KEY_INDEX_LOCK"), "exists", "60");

我预计结果将在"OK""Nil""false" 之间。我检查了文档,set 指令与'NX','EX' 将返回"OK""Nil"。 我的代码结果是在 Redis 中成功地将键 REDIS_KEY_INDEX_LOCK 设置为值 exists,但 Java 变量 result 的值是 nullredisTemplatet 变量是StringRedisTemplate 的一个实例,我使用的是Spring-Data-Redis

请帮助我,解释为什么我得到了意想不到的结果以及如何纠正它。

【问题讨论】:

【参考方案1】:

看了Spring-Data-Redis源码我知道原因了,脚本的返回类型需要明确指定。

DefaultRedisScript<String> script = new DefaultRedisScript<>();
script.setScriptText("if not redis.call('get', KEYS[1]) \n" +
            "then if(redis.call('set', KEYS[1], ARGV[1],'EX',ARGV[2],'NX'))  \n" +
            "    then return \"true\";\n" +
            "    else return \"false\";\n" +
            "end\n" +
            "else return \"false\";\n" +
            "end");
script.setResultType(String.class);//need to specify return type explicitly
String result = redisTemplate.execute(script,
            Collections.singletonList("REDIS_KEY_INDEX_LOCK"),"exists","60");

return result.equals("true");

【讨论】:

以上是关于Redis 分布式锁混淆结果与 Lua 脚本的主要内容,如果未能解决你的问题,请参考以下文章

Redis中使用Lua

使用RedisTemplate+Lua脚本实现Redis分布式锁

Redis 中使用 Lua 脚本

REDIS09_分布式锁的概述加锁使用sexnu解锁使用lua脚本保证原子性引发的问题思考

redis分布式锁和lua脚本

redis必会基础命令数据结构lua脚本和分布式锁等