Redis实现可重入的分布式锁

加锁脚本

-- 加锁脚本
-- 成功返回1,失败返回-1
local key = KEYS[1]
local requestId = KEYS[2]
-- 单位毫秒
local ttl = tonumber(KEYS[3])
local result = redis.call('setnx', key, requestId)
if result == 1 then
    redis.call('pexpire', key, ttl)
else
    result = -1
    local value = redis.call('get', key)
    -- 可重入
    if (value == requestId) then
        result = 1;
        redis.call('pexpire', key, ttl)
    end
end
return result;

解锁脚本

-- 解锁脚本
-- 成功返回1,失败返回-1
local key = KEYS[1]
local requestId = KEYS[2]
local value = redis.call('get', key)
if value == requestId then
    redis.call('del', key)
    return 1
end
return -1

执行脚本代码

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class RedisLuaScriptExample {
    public static void main(String[] args) {
        JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");
        try (Jedis jedis = pool.getResource()) {
            // 读取 Lua 脚本文件
            String script = new String(Files.readAllBytes(Paths.get("lock.lua")));

            // 加载 Lua 脚本到 Redis
            String scriptSha = jedis.scriptLoad(script, "0");

            // 执行 Lua 脚本
            jedis.evalsha(script, 0); // 改一下参数

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            pool.close();
        }
    }
}
posted @ 2024-07-09 18:13  风小雅  阅读(30)  评论(0编辑  收藏  举报