基于setnx实现的分布式锁存在一下方面的问题(redisson)
1.不可重入:同一个线程无法多次获取同一把锁.比如在a方法中当前线程获取锁,而在a方法中调用b方法 有需要获取同一把锁,那么就可能产生死锁的问题.
解决:利用hash结构,记录线程标识和重入的次数,利用watchdog延续锁时间,利用信号量控制锁重试等待
缺陷:redis宕机会引起锁失效
2.不可重试的机制:在setnx中 没有过去到锁就会返回一个false,没有重试的机制.
3.超时释放:锁超时释放尽管可以避免死锁的问题,但是如果业务执行耗时较长而锁释放了,就会产生 安全隐患的问题.
.4.主从一致性:如果redis提供了主从集群,主从同步不能再延迟,当主宕机,从并未同步主中的锁数据 ,就会产生锁实现
解决:(multilock)多个独立的redis节点,必须在所有的节点都获取重入锁,才能获得成功
秒杀优惠券一人一单
local voucherId = ARGV[1]
local userId = ARGV[2]
--库存key
local stockKey ='seckill:stock:'..voucherId
--订单key
local orderKey ='seckill:order:'..voucherId
if (tonumber(redis.call('get',stockKey))<=0) then
return 1
end
if (redis.call('sismember',orderKey,userId)==1) then
return 2
end
redis.call('incrby',stockKey,-1)
redis.call('sadd',orderKey,userId)
return 0