基于redis实现可重入分布式锁

前提

redis+lua

原理

采用redis hash数据类型,实现分布式可重入锁

hash结构中存储字段value,count

value:加锁的值,重入加锁时判断当前value和传入的value是否相等,相等情况下认为是重入锁,将count加一,不等属于其他场景抢占锁,该情况下获取锁失败

锁释放时,判断value是否相等,相等情况下是当前锁持有者释放锁场景,将count减一,count为0 时,锁释放完毕,将key删除

count:重入次数

 

注:加锁次数和释放锁次数必须一致

脚本

复制代码
-- 可重入锁加锁
local lockInfo = redis.call('hmget',KEYS[1],'value','count')
local value = lockInfo[1]
local count = lockInfo[2]
local reqValue = ARGV[1]
local expireTime = ARGV[2]
-- 判断是否初次加锁
if value==false or count==false then
    -- 更新锁信息
    redis.call('hmset',KEYS[1],'value',reqValue,'count',1)
    redis.call('expire',KEYS[1],tonumber(expireTime))
    return 1
else
    -- 判断是否重入锁
    if reqValue == value then
        -- 重入锁更新次数
        count = count+1
        redis.call('hmset',KEYS[1],'count',count)
        redis.call('expire',KEYS[1],tonumber(expireTime))
        return 1
    end
    return 0
end

-- 可重入锁释放
local lockInfo = redis.call('hmget',KEYS[1],'value','count')
local value = lockInfo[1]
local count = lockInfo[2]
local reqValue = ARGV[1]
if value~=false and count~=false then
    -- 只能删除自己加锁的数据
    if value == reqValue then
        count = count-1
        if count>0 then
            -- 更新次数
            redis.call('hmset',KEYS[1],'count',count)
            return 1
        else
            -- 次数为0,此时直接删除
            redis.call('del',KEYS[1])
            return 1
        end
    else
        return 0
    end
else
    return 0
end
复制代码

 

posted @   多少幅度  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示