Redis分布式锁导致死锁、锁误删的场景及解决方法
创作时间:
作者:
@小白创作中心
Redis分布式锁导致死锁、锁误删的场景及解决方法
引用
CSDN
1.
https://blog.csdn.net/qq_33204709/article/details/139338591
Redis 天生就可以作为一个分布式系统来使用,所以它实现的锁都是分布式锁。
Redis 可以通过 setnx 命令(set if not exists)命令实现分布式锁,实现方式如下所示:
# 加锁
setnx mylock 1
# 释放锁
del mylock
通过执行结果是否为1,可以判断是否成功获取到锁,如下图所示:
Redis 分布式锁存在什么问题?
Redis 分布式锁存在两个问题:
死锁问题:如果在加锁之后,未设置过期时间、锁忘记释放、加锁后还没来得及释放锁就宕机了这3种情况都会导致死锁问题。
锁误删问题:设置了超时时间,但是线程执行超过过期时间后锁误删问题。
解决死锁问题
- 方式一:set 升级
MySQL 中解决死锁问题是通过设置超时时间,Redis 也是如此,但是问题来了,第一步先加锁,然后再设置超时时间,那么就不满足原子性了,那怎么办?
官方在 Redis 2.6.12 版本之后,新增了一个功能,我们可以使用一条命令既执行加锁操作,又设置过期时间,相当于:setnx + expire。如下图所示:
- 第1条命令加锁成功,并设置 30s 过期时间。
- 第2条命令跟在第1条命令后,还没有超过 30s,所以加锁失败。
- 方式二:setIfAbsent 新方法
setIfAbsent() 是 Redis 专门为分布式锁实现的原子操作,其中封装了获取 key、设置 key、设置过期时间等操作。
RedisUtils 工具类:
@Component
public class RedisUtils {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 原子性操作 加锁
*/
public boolean setIfAbsent(String key, String value, long timeout, TimeUnit unit) {
return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit)
热门推荐
面对肺结节,如何选择治疗方案?
私家车长时间不开和每天只开 5 公里,哪种情况更伤车?
逍遥散的主治与功能
孩子不愿与人交流?家长如何引导与鼓励
日常如何保养汽车?记住这5个让汽车寿命延长的小技巧
创造以中华优秀传统文化为核心价值的城市文明发展模式
使用AI生成金融时间序列数据,解决A股市场数据稀缺问题
信息泄露被人威胁怎么办
TPU发泡膜的最新工艺与广泛用途
月亮在这个星座的人,会维护人际的和谐,常会在关系中倾注自己的
山西昔阳大寨景区旅游攻略
沈阳特色辣炒鸡架:香辣可口的东北美味
宝宝永远睡不饱?护理长教你七妙招,搞定宝宝睡眠问题!
三极管放大电路的分析方法与等效模型
使用HDMI转DP时如何设置165HZ
半夏种子的处理方法,播种前可用多菌灵浸种
宝瓶气:传统呼吸修炼法的科学解读与实践指南
机关绩效考核管理办法怎么制定?
那些重要的质量管理图表,你都掌握了吗?
石墨烯基材料在锂电池中最新技术进展和前景展望
宠物鼠湿尾症护理指南:从清洁到饮食全方位呵护
PP化工储罐的使用温度和寿命
孩子被同学孤立,是孩子不合群吗?
如何根据“身弱水命八字喜木火”调整生活环境以增强运势
从带娃能手到职场达人 社区微业助力宝妈华丽转身
“此有故彼有,此生故彼生”,缘起,应这样理解
曝《GTA6》画面远超大镖客2!大量新细节泄露
西安十大特色美食 10 must-try foods in Xi'an
接种脊髓灰质炎疫苗后发烧该如何处理
如何长长久久爱一个人?