【redis】使用redis分布式锁

1. 最基础的应用
String lockKey="lockKey";
//使用setnx命令加锁
stringRedisTemplate.opsForValue().setIfAbsent(lockKey,value);
...
//执行业务逻辑代码完成后释放锁
stringRedisTemplate.delete(lockKey);
存在的问题:

执行业务逻辑代码时出现异常,导致锁不能被释放。

解决方案:

加try finally语句,执行出现异常也释放锁。

存在的问题:

如果在执行代码的时候web服务器宕机,锁还是不能被释放。

解决方案:

设置过期时间:

//如果10s后还没释放锁,就强制释放锁
stringRedisTemplate.expire(lockKey,10,TimeUnit.SECONDS);
存在的问题:

setnx和expire不是原子块操作

解决方案:
//使用对应的原子命令
stringRedisTemplate.opsForValue.setIfAbsent(key,value,timeout,timeunit);
存在的问题:

假设超时时间是10s,其中,A需要执行15s才能完成,B需要执行8s,C需要执行5s。那么,当A执行10s后,锁被自动释放了,但是A还在继续执行,此时,B拿到了锁,过5s后,A执行完了,然后A去执行delete(key)释放锁的时候,释放了B持有的锁(也就是删掉了redis中的一个KV而已。。),这时候C又持有锁了(又setnx成功了),过3s后,B执行完了,然后把C的锁释放了,就这样循环地释放别人的锁……

解决方案:

value存成随机的,或者和当前执行用户有关的,每个用户在释放锁的时候首先判断此时的value是不是自己添加的,以此达到只能释放自己的锁的目的。

存在的问题:

过期时间写死很容易设置不合理

解决方案:

设置分线程对锁续命,如果没有执行完,就延长持有锁的时间。

2. Redisson
用法:
RLock redissonLock=redisson.getLock(lockKey);
redissonLock.lock();
redissonLock.unlock();

后台线程每隔10s(1/3的时长)检查是否还持有锁。

存在的问题:

redis主从同步
redis主从同步好像是异步的?假设主节点一下子挂了,那么从节点还没有这个锁的信息

解决方案:

来自网友:多节点redis实现的分布式锁算法(RedLock),有效防止单点故障。
redis分布式锁的优势在于性能,zookeeper等的可靠性比redis高。

3. RedLock

待补充……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值