马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
分布式锁的根本需求
- 互斥性:在任何时间,只有一个客户端能持有锁。
- 无死锁:纵然一个客户端在持有锁的期间瓦解,其他客户端也能得到锁。
- 容错性:分布式锁的实现应该可以大概容忍部分组件的失败,比方,锁服务节点的瓦解不应该影响客户端对锁的获取。
- 可重入性:同一个客户端可以多次获取同一把锁。
媒介
为什么要利用分布式锁?
本地锁只能锁住单台呆板多线程哀求的资源
分布式锁是多台呆板共同访问redis中的一个数据,只有获取到锁的线程才气访问
注意:
在更新MySQL和Redis之前,先获取一个分布式锁。如许,只有获取到锁的线程才气实行更新操纵,从而克制了并发更新导致的数据不同等题目。
但是这种方法大概会导致性能降落和死锁的风险。因此,在利用分布式锁时须要审慎思量
怎样设置分布式锁?
图解
注意:
SETNX(SET if Not eXists):这是Redis中实现锁机制的一个根本下令。SETNX下令会实验将指定的键(key)设置为给定的值(value),假如键不存在的话。假如键已存在,则操纵无效。这可以用于实验获取锁的场景
返回值:1(不存在,设置乐成)0(存在,设置不乐成)
图表的表明
- 代码竣事要开释锁
- 利用try-finally语句:在步伐中,利用try-finally语句块来确保无论步伐是否发生非常,finally块中的代码都会被实行。如许,你可以在finally块中添加开释锁的代码,以确保在步伐制止时锁可以大概被准确开释。但是,这种方法无法办理服务器宕机或网络制止等非常情况。
- 设置锁的超时时间:为锁设置一个公道的超时时间,纵然步伐忽然制止,锁也会在超时后自动开释。这可以通过Redis的EXPIRE下令或SET下令联合EX选项来实现。如允许以克制由于步伐制止而导致的死锁题目。
准确设置值 + 逾期时间的方式:
假如你想 原子地 实现 “假如 key 不存在就设置值并设置逾期时间”,保举利用 SET 下令的扩展参数: SET key value NX EX 60
springboot中利用 SET key value NX EX 60 :- Boolean success = stringRedisTemplate.opsForValue().set(
- key,
- value,
- Duration.ofSeconds(60),
- RedisStringCommands.SetOption.ifAbsent() // 对应 NX
- );
复制代码
假如锁设置的逾期时间到了,但是步伐还没有实行完,这种情况怎么办理?
办理方案:
1.增长锁的超时时间:假如任务确实须要较长时间来完成,而且你可以继承更长的期待时间,那么你可以思量增长锁的超时时间。但请注意,过长的超时时间大概会增长死锁的风险,由于假如一个历程持有锁并由于某种缘故起因瓦解或进入长时间壅闭状态,那么其他期待该锁的历程大概会被壅闭很长时间。
2.锁续命(Lock Renewal):假如锁支连续命操纵(如Redisson中的看门狗机制),你可以实验在锁到期之前重新设置或延伸其超时时间。这通常通过一个定时任务或背景线程来实现,定期查抄锁的状态并在须要时续命。但请注意,这须要在锁被开释之前完成,否则大概会导致竞争条件。
下面引入一张图解更好的明白看门狗机制
|