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)
热门推荐
夏斌教授推荐:幼儿牙齿保护秘籍
普洱太阳河国家公园:动植物王国里的摄影天堂
普洱必打卡!茶马古道&那柯里古镇美照攻略
AI赋能:现代战争中的网络空间态势感知
春节将至,冰雪经济爆火
最新态势感知技术:企业安全防护新利器
情感冲突中的理智与温柔:如何处理三角关系?
冲突后的冷静与应对:一个实用指南
云水谣古镇:从电影到现实,探寻福建土楼背后的故事
厦门泉州4天自驾游,跟着网红攻略嗨翻天!
《爱情公寓》教你如何克服异地恋孤独感
福哥揭秘异地恋保鲜秘籍:沟通与信任的艺术
山东济宁“6大美食”,看着就流哈喇子,你吃过几种
山东济宁:11处最值得推荐的名胜古迹
全屋WiFi无死角攻略:信号放大器、路由桥接、子母路由、POE交换机方案详解
WIFI信号增强秘籍:自制天线的原理与实践
天线数量与路由器信号:真相与误区
MBTI性格测试:从聊天中识破16种性格类型
职场沟通致胜法则:从倾听到反馈的全方位提升
跨文化交流:如何适应不同对话风格?
喉咙“长结石”,扁桃体结石怎么回事?
扁桃体结石的处理方法
扁桃体结石怎么样自己清理
扁桃体炎 不要让它影响您的生活质量
扁桃体及扁桃体炎症是怎么回事?
职场冲突解决秘籍:构建和谐关系
美国约翰·霍普金斯医院研发出胰腺癌早期筛查新利器,癌前病变无所遁形!
圆明园:300年园林的兴衰史,一砖一瓦都藏着故事
为什么“文”在谥号中属于美谥,在庙号中属于明褒实贬?
《蛊真人》手游上线:仙魔对决,你的选择决定命运