千家信息网

redis发生死锁问题怎么办

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,这篇文章主要介绍了redis发生死锁问题怎么办,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。就分布式锁而言,一个常用的问题就是如果一个服务
千家信息网最后更新 2024年11月18日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安全错误 数据库的锁怎样保障安全 网络安全移动员工 北京至臻互联网科技有限公司 深圳卡尔迅互联网科技有限公司怎么样 杨浦区质量网络安全创新服务 农牧民网络安全知识资料 网络安全法规定的个人信息包括 上海富友网络技术有限公司 中晋 SEO写作软件开发 方舟手游自己的服务器多少钱 dell首款军事服务器 深信服防火墙防护服务器 软件开发费进成本 数据库建模工具制作 北京少儿编程平台软件开发 网络安全与管理专业期末考试 江湖网络安全防护指南 网络技术发展面临注意的问题 网络安全公司最新排名 域同步文件服务器 服务器管理器是什么 sql修改数据库路径 个人搭配一个视频服务器腾讯云 软件开发小工具有哪些 夯实网络安全基石 贵州网络安全系统费用多少 着力增强网络安全意识 无锡现代软件开发工具技术参数 网络安全法规定 有关部门 保证银行数据库安全性 向量数据库使用场景
0