前提
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
标签:重入,count,--,redis,value,call,local,分布式 From: https://www.cnblogs.com/tangs1/p/18231466