redis实现分布式锁踩坑记录[亲测有效]

redis实现分布式锁踩坑记录[亲测有效]业务场景 我的业务场景是这样的,我们服务有库存模块,而我的服务又是多节点部署,要高峰期会存在库存差异,后面分析问题之后,打算采用redis实现分布式锁(主要的原因是服务已经集成了redis,不需要做…

redis实现分布式锁踩坑记录

业务场景

我的业务场景是这样的,我们服务有库存模块,而我的服务又是多节点部署,要高峰期会存在库存差异,后面分析问题之后,打算采用redis实现分布式锁(主要的原因是服务已经集成了redis,不需要做额外的配置)

踩坑1. 数据库事务超时

不要感觉奇怪,分布式锁怎么会导致数据库事务超时呢?
我的代码大概是这样的:

伪代码
@Transaction(readOnly=false)
void update(){
    do{
        redis=JedisUtil.getJedis();
        flag = getLock(key,redis);
        if(flag){
            update();
        }
    }while(true)
}

代码100分

当你的key长时间获取不到锁,并且数据库事务都有超时时间的限制,那么就会出现数据库事务超时问题;
解决方案

数据库事务改为手动提交事务;

踩坑2. redis key过期,而业务没有执行完

我的key的过期时间设置的是30s,如果30秒业务还没有执行完毕,锁就会自动释放,锁释放之后,其它线程又会去占用锁,同样会导致问题的发生;
解决方案

最简单的解决方案就是使用redisson;
如果非要用redis来解决的话,只能使用定时器去检测key,如果说key还有2秒就快过期了,那么再为key重新设置30秒的过期时间;

踩坑3. redis连接池爆满

分布式锁刚加上之后,生产出现一个问题,就是:redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
解决办法
开始查代码,发现是开发人员没有对连接进行释放;

修复bug之后,又在线上跑了一段时间,又出现了redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
解决办法

代码100分void update(){
    do{
        redis=JedisUtil.getJedis();
        flag = getLock(key,redis);
        if(flag){
            update();
        }else{
            // 释放当前redis连接
            // 由于我们的业务场景属于比较耗时的业务型,所以在这里休眠1000毫秒
            redis.close();
            sleep(1000);
        }
    }while(true)
}

1.当前请求获取锁,如果获取不到,则释放当前连接,并休眠一会;
2.合理配置redis连接池大小,主要参考具体业务场景的并发量来设置;郑州不孕不育医院哪里好:http://byby.tjyy120.com/

踩坑4. 解铃还须系铃人

回顾一下加锁的参数:

set(key, vlue,"NX","PX", 30000);

其中:value,我使用它来表示加锁人,必须是一个唯一的标识

比如:
A线程 key=test value=01
B线程 key=test value=02

如果A线程执行业务耗时超过了锁的持有时间,锁会自动释放;锁自动释放之后,线程B又加锁成功,但是,此时A线程执行完业务逻辑之后,去释放锁,但A线程的锁已经自动释放了,如果没有value来标识的话,它可能就会去释放B线程的锁;

踩坑5. redis集群实现分布式锁

这种情况我没有遇到,因为公司的redis集群做了改进;

先说一下这种问题产生的原因:
如果master节点由于某原因发生了主从切换,那么就会出现锁丢失的情况;

  • 在master节点上拿到了锁;
  • 但是这个加锁的key还没有同步到slave节点;
  • master故障,发生故障转移,slave节点升级为master节点;郑州的不孕不育医院哪家好:http://jbk.39.net/yiyuanfengcai/tsyl_zztjyy/3031/
  • 故导致锁丢失;

解决办法

需要通过使用redlock算法;
或使用redisson,它有对redlock算法做封装;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8871.html

(0)
上一篇 2023-02-20 13:30
下一篇 2023-02-20

相关推荐

  • 截取中间字符串的函数_sprintf函数的用法

    截取中间字符串的函数_sprintf函数的用法Excel中的函数非常多,但能记住并且真正能运用到实际工作中的人很少。很多小伙伴都问我怎样才能快速记住函数,答案只有一个:多练。不过学习总是有方法的,下面归类了8组文本函数,这样子可以助你快速掌握Excel文本函数的使用,记得转发收藏起来哦~一、文本中提取字符函数——Left函数、Right函数、Mid函数。LEFT函数:用于对单元格的内容进行截取。从左边第一个字符开始截取,截取指定的长度。RIG…

    2023-03-01
    139
  • Python工程师的Opencv安装指南

    Python工程师的Opencv安装指南Opencv(Open Source Computer Vision)是一个广泛使用的计算机视觉开源库,适用于工业图像处理、机器人视觉等领域。由于其功能强大,Opencv被广泛应用于图像处理、人脸检测、目标跟踪、运动分析、手势识别等领域中。

    2024-06-05
    67
  • MySQL原理 – InnoDB引擎 – 行记录存储 – Compact 行格式

    MySQL原理 – InnoDB引擎 – 行记录存储 – Compact 行格式MySQL 服务器上负责对表中数据的读取和写入工作的部分是存储引擎,比如 InnoDB、MyISAM、Memory 等等,不同的存储引擎一般是由不同的人为实现不同的特性而开发的,目前OLTP业务的表…

    2023-03-17
    170
  • 终于有人把不同标签的加工内容与落库讲明白了丨DTVision分析洞察篇

    终于有人把不同标签的加工内容与落库讲明白了丨DTVision分析洞察篇上一篇文章详细给大家介绍了标签的设计与加工,在标签生命周期流程中,标签体系设计完成后,便进入标签加工与上线运行阶段,一般来说数据开发团队会主导此过程,但我们需要关心以下几个问题: ·标签如何

    2023-06-04
    147
  • 【MySQL】LIMIT以及LIMIT OFFSET「建议收藏」

    【MySQL】LIMIT以及LIMIT OFFSET「建议收藏」LIMIT两种方法: 1 两种方法: 2 (1)LIMIT A; 3 #表示从第一条记录开始取A条记录; 4 5 (2)LIMIT A,B; 6 #参数A为可选参数,表示跳过A条数据(默认为0) 7

    2022-12-26
    161
  • 37-SQLServer的审核/审计功能介绍「建议收藏」

    37-SQLServer的审核/审计功能介绍「建议收藏」 一、总结 1、SQLServer2008开始支持审计功能,审计规范分为服务器级别和数据库级别两种; 2、无论是服务器级别的审计还是数据库级别的审计,第一步创建审计对象的方式一样,最后创建完都…

    2023-03-26
    140
  • 如何使用 SQL WHERE 过滤返回的数据「终于解决」

    如何使用 SQL WHERE 过滤返回的数据「终于解决」本文介绍如何使用 SQL WHERE 子句指定搜索条件,过滤返回的数据。还介绍如何检验相等、不相等、大于、小于、值的范围以及 NULL 值等。 一、使用 WHERE 子句 数据库表一般包含大量的数据,

    2023-05-13
    143
  • 有关条形码打印太浅或太深的原因及解决方法[通俗易懂]

    有关条形码打印太浅或太深的原因及解决方法[通俗易懂]近来有客户咨询,在条码生成软件生成条形码之后,连接打印机进行打印的时候,打印出来的条形码不是太深就是太浅,咨询这是怎么回事,该怎么解决?首先这里跟大家说下,出现这种情况,跟条码生成软件没有关系,你可…

    2023-04-04
    189

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注