RedisTemplate实现锁超时时间延长(模仿Redisson看门狗机制)

业务场景:

在上一篇-Java业务功能并发问题处理的最后,我们用RedisTemplate实现了一个分布式锁,但是后面又有用户反馈同个单据出现了重复操作,让我们回忆下上次的加锁代码:
分布式锁请求锁逻辑


问题描述:

原因出现在我们锁住的那段代码执行了太久,超过预设的过期时长。在A线程还在执行中时,Redis中作为锁的key已经过期了,当B线程进入时判断已经没有锁了,因此允许执行。

解决方案分析:

由于我们不知道业务需要执行多久,需要一个机制在过期前检查是否线程还在运行中(为什么必须是过期前?因为过期了我们就无法知道线程是超时导致的解锁还是线程主动的解锁。),如果线程仍在运行,则将过期时间延长。下面绘制一个流程图让大家更直观地了解整个流程,此处是模仿Redisson看门狗机制
仿造看门狗机制流程图

代码实现:

// ...省略循环等代码
isSuccessLock = redisTemplate.opsForValue().setIfAbsent(redisKey, Thread.currentThread().getName(), lockTime, TimeUnit.MILLISECONDS);
if (Boolean.TRUE.equals(isSuccessLock)) {// 新增的重置过期时间方法 在加锁成功后, 开启1个线程, 做redis看门狗机制renewExpiration(lockKey, Thread.currentThread().getName(), lockTime);return true;
}
// 省略for循环中的try...catch代码

renewExpiration刷新锁时间的方法实现

/*** lua脚本 更新锁时间, 如果已经获取不到值, 则不更新锁的过期时间*/
private static final String REDIS_RENEW_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] " +"then return redis.call('expire', KEYS[1], ARGV[2]) " +"else return 0 end";
/*** 刷新锁时间* @param lockKey   锁key* @param requestId 锁线程号,redis的value* @param lockTime  锁时长*/
public void renewExpiration(String lockKey, String requestId, long lockTime) {DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(REDIS_RENEW_LOCK_SCRIPT, Long.class);// 通过线程池创建异步线程taskExecutor.execute(() -> {while (true) {try {// 等待锁时长的1/3后刷新锁的过期时间Thread.sleep(lockTime / 3 * 1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}// 当前template只能传字符串, 将时间转为字符串传入String timeStr = String.valueOf(lockTime);// 延长过期时间原子操作Long execute = redisTemplate.execute(redisScript, new ArrayList<>(Collections.singleton(lockKey)), requestId, timeStr);if (execute == null || execute == 0) {break;}}});
}

总结:

其实后面才了解到Redis的分布式锁直接引入Redisson就万事大吉了,建议大家直接通过Redisson去做Redis的分布式锁,省时省力,方便完善。此处自己写其实也是为了更深入了解分布式锁的实现,而且一开始觉得就一个类解决的事情,引入多余的一个工具包会不会有点多余,结果做到后面才发现也有一些坑是自己没考虑周到的。等我后面有时间一定直接引入Redisson

参考链接:

redission的看门狗机制及应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/746827.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Halcon的了解

Halcon介绍_halcon是什么软件-CSDN博客 德国Mvtec公司开发的一套完善的标准的机器视觉算法包。 Halcon:底层功能算法多&#xff0c;运算性能快&#xff0c;开发需要一定的软件功底和图像处理理论。 它其实是具体的实现功能的算法包。可以跟Qt结合使用。 需求&#xff1a; 二维&…

【开源工程】超经典实景三维数字孪生矿山~智慧矿山解决方案

飞渡科技数字孪生煤矿管理平台&#xff0c;以数字孪生技术为底座&#xff0c;融合图像识别、电磁感应、5G下井等技术&#xff0c;实现矿山环境、采煤装备、移动巡检等生产数据的全面采集&#xff0c;实时感知生产过程与关键装备的运行数据和状态&#xff0c;逐步推进矿山全流程…

电商数据分析22——电商平台交叉销售策略的数据分析

目录 写在开头1. 交叉销售策略的基本原理1.1 交叉销售的精髓1.2 定义与目标1.3 对电商增收的贡献 1.4 深挖数据&#xff0c;揭示机会2.1 用户购买行为分析2.2 商品关联规则挖掘2.3 个性化推荐算法的优化 3. 交叉销售策略的实施案例3.1 案例分析&#xff1a;提升购物车平均价值3…

Redis是如何实现持久化的?请解释RDB和AOF持久化方式的区别和优缺点。Redis是单线程还是多线程的?为什么Redis使用单线程模型仍然能保持高性能?

Redis是如何实现持久化的&#xff1f;请解释RDB和AOF持久化方式的区别和优缺点。 Redis实现持久化主要有两种方式&#xff1a;RDB&#xff08;Redis DataBase&#xff09;和AOF&#xff08;Append Only File&#xff09;。这两种方式的主要区别在于它们的持久化机制和适用场景。…

【趣味学算法】07_爱因斯坦的数学题

注&#xff1a; 本系列仅为个人学习笔记&#xff0c;学习内容为《算法小讲堂》&#xff08;视频传送门&#xff09;&#xff0c;通俗易懂适合编程入门小白&#xff0c;需要具备python语言基础&#xff0c;本人小白&#xff0c;如内容有误感谢您的批评指正 有一条长阶梯&#xf…

Python爬虫从基础到入门:script标签中的数据

上一篇文章: Python爬虫从基础到入门:script标签中的数据 1. 分析需要抓取的数据的在哪?2. 获取数据、解析数据3. 下载视频、音频文件4. 参考代码1. 分析需要抓取的数据的在哪? 本篇博文以B站视频为例,B站视频在用户没有登录的状态下,只能观看视频尺寸为360流畅,在登录…

深度剖析Kafka中Coordinator的奥秘

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 深度剖析Kafka中Coordinator的奥秘 前言什么是Coordinator&#xff1f;Group Coordinator&#xff08;群组协调器&#xff09;&#xff1a;Transaction Coordinator&#xff08;事务协调器&#xff09…

一文让您读懂实时数仓(Apache Doris)

引言&#xff1a; 随着大数据时代的来临&#xff0c;实时数据处理与分析成为企业核心竞争力的关键因素之一。在这场数据革命中&#xff0c;SelectDB成为引领者。从百度自研的实时数仓平台 Palo&#xff0c;到开源项目 Apache Doris&#xff0c;再到飞轮科技研发的 SelectDB&am…

程序人生——Java数组和集合使用建议(1)

目录 引出数组和集合建议60&#xff1a;性能考虑&#xff0c;数组是首选建议61&#xff1a;若有必要&#xff0c;使用变长数组建议62&#xff1a;警惕数组的浅拷贝 建议63&#xff1a;在明确的场景下&#xff0c;为集合指定初始容量建议64&#xff1a;多种最值算法&#xff0c;…

使用opencv进行图片分析

opencv学习 一、配置环境并打开编译器 配置opencv在你的任意一个盘里创建一个专属于opencv的文件夹便于学习与整理 打开控制台winr输入cmd&#xff0c;进入后输入conda activate opencv&#xff0c;进入环境以后进入你所设置的opencv文件的盘&#xff0c;我的是D盘&#xff0…

php.exe运行时,提示缺少VCRUNTIME140.dll

php.exe运行时&#xff0c;提示缺少VCRUNTIME140.dll 下载地址 https://www.microsoft.com/zh-cn/download/details.aspx?id48145根据需要选择下载3.运行安装后&#xff0c;再次运行php.exe。

JAVA后端编码的主键字段存储为什么倾向于使用雪花算法

1.背景 最近有人问&#xff0c;什么是雪花算法&#xff0c;为什么使用雪花算法不使用数据库UUID&#xff0c;基于此&#xff0c;写一个说明。 2.简介 &#xff08;1&#xff09;雪花算法&#xff0c;英文名为snowflake&#xff0c;翻译过来就是是雪花&#xff0c;所以叫雪花…

javaweb篇请求与相应的参数问题

目录 目录 前言 简单传参设置 get请求无法识别 post请求 简单传参问题无法识别的解决问题 注意事项 改法 实体参数 代码展示&#xff08;1&#xff09;------单个私有类 代码展示&#xff08;2&#xff09;----多个私有类 实现服务器的部署以及实参的传递 今日分享…

B3620 x 进制转 10 进制(详解)

题目 思路 八进制数567怎么转化为十进制数。首先八进制就是逢八进一&#xff0c;也就是说这里面最大的数也就7&#xff0c;没有≥8的数。下面我们就讲一下567怎么转化为十进制&#xff1a;首先7是个位&#xff0c;可以直接写成十进制的7&#xff0c;6是十位&#xff0c;它是通…

图片制作二维码能批量生成吗?快捷在线制作二维码的技巧

现在很多场景下获取内容的方式都会通过扫描二维码来获取&#xff0c;比如常见的有文本内容、图片照片、音频视频等。二维码制作的方法也越来越简单&#xff0c;只需要通过二维码生成器的功能就可以快速完成&#xff0c;那么如果需要将多张图片每一张单独生成二维码使用时&#…

虚幻引擎5比Maya更好用吗?来看看Maya大神眼中的虚幻引擎5

这两年&#xff0c;大家总在争论&#xff1a; 虚幻引擎5&#xff08;UE5&#xff09;比Maya更好用吗&#xff1f; 未来会替代Maya吗&#xff1f; 虚幻引擎5(UE5)的快速发展&#xff0c;让许多传统Maya动画师感到焦虑和迷茫。但不要担心&#xff0c;这篇文章旨在解决你的困扰。…

Springboot——JSR303校验

1. 请求参数的合法性校验 使用基于JSR303的校验框架实现&#xff0c;Springboot提供了JSR-303的支持&#xff0c;它就是spring-boot-starter-validation&#xff0c;他包括了很多的校验规则&#xff0c;只需要在模型中通过注解指定校验规则&#xff0c;在Controller方法上开启校…

卫星参数转换之二行转轨道六根数转经纬度坐标

生命无罪&#xff0c;健康万岁&#xff0c;我是laity。 我曾七次鄙视自己的灵魂&#xff1a; 第一次&#xff0c;当它本可进取时&#xff0c;却故作谦卑&#xff1b; 第二次&#xff0c;当它在空虚时&#xff0c;用爱欲来填充&#xff1b; 第三次&#xff0c;在困难和容易之…

Linux关机和重启指令

关机 立即关机指令如下&#xff0c; sudo shutdown -h now 延迟关机指令如下&#xff0c;&#xff08;5表示5分钟后执行该操作&#xff09; sudo shutdown -h 5 重启 立即重启指令如下&#xff0c; sudo shutdown -r now 延迟重启指令如下&#xff0c; sudo shutdow…

【Android】源码中的工厂方法模式

本文是基于 Android 14 的源码解析 工厂方法模式应用很广泛&#xff0c;我们平时开发中经常会使用到的数据结构中其实也隐藏着对工厂方法模式的应用&#xff0c;以 List 和 Set 为例&#xff0c;List 和 Set 都继承于 Collection 接口&#xff0c;而 Collection 接口继承于 Ite…