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)
热门推荐
两杠两星是什么军衔及其晋升参考因素
为什么需要定期更新固定资产明细表?
干槽症一般在拔牙后几天出现?常高发于拔牙后3~5天,附干槽症产生原因及治疗方案
一文从 0 到 1 了解量子计算
如何写赋:从种类、特点到写作技巧的全面解析
甜食对大脑的危害有多严重
构建稳健投资组合:ETF策略应用指南
《真三国无双起源》二周目内容详解:新增高难度挑战、新武器与系统
薯片的热量:美味与健康的平衡
所以,不叫“大姐”叫什么?
甲状腺功能亢进症的中药治疗方剂
奥克斯中央空调故障解决方案(解决奥克斯中央空调常见故障的方法及技巧)
FPS是什么意思?数值影响与游戏体验详解
上海枫泾古镇游玩全攻略:景点、美食与路线推荐
好听游戏角色名字,游戏角色名名字
健康服务与管理专业求职者怎样写好技能特长
AI新型诈骗频发,三类骗局防范指南
四级语法单位之间的关系
供车时如何选择合适的车挂件?车挂件对车内装饰有何作用?
十大适合煮茶的茶,哪种味道醇厚?
31省份人均GDP大洗牌:十地超10万元,山西跌出20强
石斛的功效和作用及食用方法
清晰表达:如何在拥挤的PPT中传递重点信息
在美国进行境外汇款、转账什么时候需要报税?很多华人不知道
什么是命格?命格有哪几种?
必学椰香秘籍!9款椰浆饮品DIY,轻松变身调饮大师
二十世纪初欧洲反犹主义的三大根源
如何安全使用境外IP地址:保护个人隐私的实用指南
教学评价八种方法是什么?
马克思预言资本主义社会系统崩溃为什么还没有实现?