使用 RedisTemplate 执行 lua 脚本时出现混淆的结果

我正在使用 spring-boot-starter-data-redis 2.0.5.RELEASE。我使用 RestTemplate 执行 lua 脚本。

脚本:

-- hold.lua
if redis.call('get', KEYS[1]) == ARGV[1] then
    redis.call('pexpire', KEYS[1], ARGV[2])
    return 1
end
return 0

Java 代码:

@Override
public void executeHold(String lockKey, String lockValue, long expireInMillis) {
    DefaultRedisScript<Boolean> holdScript = new DefaultRedisScript<>();
    holdScript.setLocation(new ClassPathResource("lua/hold.lua"));
    holdScript.setResultType(Boolean.class);
    // 代码 1
    Boolean result = redisTemplate.execute(holdScript, Collections.singletonList(lockKey), lockValue, expireInMillis);
    // 代码 1 结束
    //        // 代码 2
    //        String script = holdScript.getScriptAsString();
    //        Boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
    //            @Override
    //            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
    //                return connection.scriptingCommands()
    //                        .eval(
    //                                script.getBytes(),
    //                                ReturnType.fromJavaType(Boolean.class),
    //                                1,
    //                                lockKey.getBytes(),
    //                                lockValue.getBytes(),
    //                                String.valueOf(expireInMillis).getBytes()
    //                        );
    //            }
    //        });
    //        // 代码 2 结束
    System.out.println(holdScript.getSha1());
    LOGGER.debug("执行 holdScript,结果={},内容=\n{}", result, holdScript.getScriptAsString());
}

我已经在 redis 中设置了 lockKey

127.0.0.1:6379> set lockKey lockValue PX 600000 NX

当我运行上述代码,并使用 代码 1 时,我总是得到 result = false 的结果。

但当我改变上述代码,使用 代码 2 时,我可以正常得到结果。

这真的让我感到困惑,有谁能帮助我找出问题出在哪里?谢谢。

我想要做的事情在 这里

点赞
用户7544254
用户7544254

我曾面临类似的问题。我问题的本源是我在 redis 模板中使用了 json 序列化器,它在我传递到脚本中的字符串值中添加了额外的引号。将序列化器更改为字符串序列化器解决了我的问题。

2020-06-05 15:56:14