redis发生死锁问题怎么办
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要介绍了redis发生死锁问题怎么办,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。就分布式锁而言,一个常用的问题就是如果一个服务
千家信息网最后更新 2025年02月01日redis发生死锁问题怎么办
这篇文章主要介绍了redis发生死锁问题怎么办,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。
就分布式锁而言,一个常用的问题就是如果一个服务setnx成功了,但是在解锁的时候如果发生了宕机或者一些特殊因素,导致无法解锁,那么其他服务将陷入死锁的状态。所以,我们在用 setnx 的同时想着去用 expire 指令对锁进行一个过期操作, 从指令可以看出 setnx 和expire指令是分开的,如果在这中间的空隙过程中如果有特殊因素导致指令无法继续,也会导致死锁的产生。
解决方法:
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils; @Componentpublic class RedisLock { Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private StringRedisTemplate redisTemplate; /** * 加锁 * @param key * @param value 当前时间 + 超时时间 * @return */ public boolean lock(String key, String value) { if (redisTemplate.opsForValue().setIfAbsent(key, value)) { // 这个其实就是setnx命令,只不过在java这边稍有变化,返回的是boolean // 设置个过期时间,当然如果在这中间的空隙过程中如果有特殊因素导致指令无法继续,也会导致死锁的产生,如果死锁出现,则后续代码会处理 redisTemplate.expire(key, lockTime, TimeUnit.SECONDS); return true; } // 避免死锁,且只让一个线程拿到锁 String currentValue = redisTemplate.opsForValue().get(key); // 如果锁过期了 if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) { //获取上一个锁的时间 String oldValues = redisTemplate.opsForValue().getAndSet(key, value); /* 只会让一个线程拿到锁 如果旧的value和currentValue相等,只会有一个线程达成条件,因为第二个线程拿到的oldValue已经和currentValue不一样了 */ if (!StringUtils.isEmpty(oldValues) && oldValues.equals(currentValue)) { return true; } } return false; } /** * 解锁 * @param key * @param value */ public void unlock(String key, String value) { try { String currentValue = redisTemplate.opsForValue().get(key); if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) { redisTemplate.opsForValue().getOperations().delete(key); } } catch (Exception e) { logger.error("redis分布式锁解锁异常,{}", e); } }}
调用:
//加锁 long time = System.currentTimeMillis() + 1000 * lockTime //超时时间:10秒,最好设为常量 boolean isLock = redisLock.lock(...keyName, String.valueOf(time)); if(!isLock){ throw new RuntimeException("系统正忙"); } // doSomething... //解锁 redisLock.unlock(...keyName, String.valueOf(time));
感谢你能够认真阅读完这篇文章,希望小编分享redis发生死锁问题怎么办内容对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,遇到问题就找,详细的解决方法等着你来学习!
死锁
指令
时间
问题
线程
特殊
因素
篇文章
怎么办
分布式
同时
就是
方法
空隙
过程
服务
成功
代码
价值
内容
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络技术相关认证有哪些
怎么登录我的世界神奇宝贝服务器
小视频制作软件开发
数据库100多g
找软件开发流程的8个步骤
设计单位项目管理软件开发价格
深圳社交软件开发咨询
计算机网络安全与病毒防范
换电脑 财务软件数据库
dell r330服务器
mysql初级数据库问题
政府部门软件开发
重庆小学教育与网络安全
苏州电脑软件开发培训
软件开发预算评审方案
威海管理软件开发产品
曹戈展硕网络技术服务有限公司
华为手机不显示动数据库
常州方便软件开发商家
数据库并表
数据网络安全公开课
广州纺织软件开发
怎么设置连接的网络安全
网络安全性能测试 ppt
bvd系列数据库
注意网络安全的班会
网络安全要解决哪些问题
数据库分离怎么设置
网络安全面临的困难
数据库职工工资数据库