分布式锁-数据库锁

本文主要分享如何使用数据库乐观锁的方案,实现分布式定时任务抢锁执行任务的场景,避免重复执行任务。

案例技术:Oracle+SpringBoot+xxl-Job

环境准备

xxl-Job部署请移步:Spring+xxl-job+oracle_xxl-job oracle配置-CSDN博客

SpringBoot代码:截取核心

说明:本项目存在业务需要处理的作业,产生一条就会存入test_process表一条stauts=1的记录。由于该服务部署了多个示例,执行器也分布在每一个实例中,故当多个定时任务同时执行时,会出现重复执行。

 1、获取任务

        路由策略采用分片广播策略,将任务均分到各个执行器。

// 路由策略采用分片广播,将任务均匀分布到各个执行器
@Select("select * from test_process t where  t.id % #{shardTotal} = #{shardIndex} and t.status=1 and t.fail_count<3")
List<TestProcess>  selectListByShardIndex(@Param("shardTotal") int shardTotal, @Param("shardIndex") int shardIndex );

   2、定义Job

@XxlJob("testJobHandler")
public void testJobHandler() throws Exception {// 分片参数int shardIndex = XxlJobHelper.getShardIndex();//执行器的序号,从0开始int shardTotal = XxlJobHelper.getShardTotal();//执行器总数//查询待处理的任务List<TestProcess> processList = processService.selectListByShardIndex(shardIndex, shardTotal);//任务数量int size = processList.size();if(size<=0){return;}//创建一个线程池ExecutorService executorService = Executors.newFixedThreadPool(size);//使用的计数器CountDownLatch countDownLatch = new CountDownLatch(size);mediaProcessList.forEach(testProcess -> {//将任务加入线程池executorService.execute(()->{try {//任务idLong taskId = testProcess.getId();//开启任务int count = processService.startTask(taskId);if (count<=0) {log.debug("抢占任务失败,任务id:{}", taskId);return;}// 抢占成功,执行任务executeTask(testProcess);// 更新状态saveProcessFinishStatus(testProcess);}catch(Exception e){return;}		finally {//计算器减去1countDownLatch.countDown();}});});
}

3、 定义乐观锁

        在持久层定义乐观锁,确保只有一个线程抢到锁。并定义最大重入三次。

// 持久层,定义乐观锁
@Update("update test_process m set m.status='2' where m.status='1' and m.fail_count<3 and m.id=#{id}")
int startTask(@Param("id") long id);

4、执行任务后处理

public void saveProcessFinishStatus(TestProcess testProcess) {testProcess.setStatus("2");processService.updateById(testProcess);}

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

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

相关文章

人工智能算法工程师(高级)课程7-图像分割项目之DeepLab模型的搭建与代码详解

大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程7-图像分割项目之DeepLab模型的搭建与代码详解。本文将详细介绍DeepLab模型的关键组成部分,包括Image Pyramid、Encoder-Decoder、SPP模型和ASPP模型。我们将从数学原理出发,配合LaTeX公式,并使用PyTorc…

关于珞石机器人二次开发SDK的posture函数的算法RX RY RZ纠正 C#

在珞石SDK二次开发的函数钟&#xff0c;获取当前机器人位姿的函数posture函数在输出时会发现数据不正确&#xff0c;与示教器数据不一致。 其中第一个数据正确 第二三各数据为相反 第四五六各数据为弧度制 转换方法为(弧度/PI)*180度 然后发现第四个数据还要加上180度 第五…

docker Docs相关使用文档链接

Docker Docshttps://docs.docker.com/ docker compose | Docker Docshttps://docs.docker.com/reference/cli/docker/compose/docker | Docker Docshttps://docs.docker.com/reference/cli/docker/

工作很难受,还要不要继续留在职场上?

先说结论&#xff1a;我非常赞同大家离开职场 虽然小编现实的工作是有关于人力资源的&#xff0c;高级点叫做猎头&#xff0c;低俗点讲就叫“人贩子” 原因可能和其他人不太一样&#xff0c;大家自行理解 1.现在的社会资源太少&#xff0c;“蛋糕”太小 大家要明白最重要的…

Ethernet

目录 1. Physical Layer(PHY)2. MAC2.1. MAC帧格式2.2. MAC地址与IP地址3. RGMII接口FPGA实现以太网(一)——以太网简介 以太网(Ethernet)是指遵守 IEEE 802.3 标准组成的局域网通信标准, IEEE 802.3 标准规定的主要是OSI参考模型中的物理层(PHY)和数据链路层中的介质访问控…

【HZHY-AI300G智能盒试用连载体验】设置RKNN的开发环境

目录 安装RKNN工具 安装pip3 安装RKNN Toolkit Lite2 安装RKNPU2运行库 本文首发于电子发烧友论坛&#xff1a;【新提醒】【HZHY-AI300G智能盒试用连载体验】 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 前…

kubevirt中disk的bus类型

在 KubeVirt 中&#xff0c;定义虚拟机中磁盘&#xff08;disk&#xff09;的时候&#xff0c;可以指定不同的总线&#xff08;bus&#xff09;类型&#xff0c;以确定磁盘如何与虚拟机中的虚拟硬件进行通信。以下是 KubeVirt 中常见的磁盘总线类型&#xff1a; Virtio 类型: v…

go语言day20 使用gin框架获取参数 使用自定义的logger记录日志

Golang 操作 Logger、Zap Logger 日志_golang zap-CSDN博客 一、 从控制器中获取参数的几种形式 1&#xff09; 页面请求url直接拼接参数。 2&#xff09; 页面请求提交form表单 3&#xff09; 页面请求发送json数据&#xff0c;使用上下文对象c的BindJSON()方法接收数据…

SQL Server审计:深入掌握SQL Server Audit的高级应用

SQL Server审计&#xff1a;深入掌握SQL Server Audit的高级应用 SQL Server提供了强大的审计功能&#xff0c;允许数据库管理员(DBA)跟踪和记录数据库活动&#xff0c;确保数据库的安全性和合规性。SQL Server Audit是实现这一目的的关键工具之一。本文将详细介绍如何在SQL S…

CI/CD:Job failed: execution took longer than 1h0m0s seconds

简介&#xff1a;当在CI/CD配置运行Gitlab-runner流水线中&#xff0c;一般默认情况下&#xff0c;Job的执行时间默认为1小时&#xff0c;如果超出1小时&#xff0c;任务会中断。 历史攻略&#xff1a; 定时任务&#xff1a;Jenkins 容器化CICDLocust性能压测 容器化CICDSo…

Python学习和面试中的常见问题及答案

整理了一些关于Python和机器学习算法的高级问题及其详细答案。这些问题涵盖了多个方面&#xff0c;包括数据处理、模型训练、评估、优化和实际应用。 一、Python 编程问题 解释Python中的装饰器&#xff08;Decorators&#xff09;是什么&#xff1f;它们的作用是什么&#xf…

【C++ —— 认识哈希和unordered_set、unordered_map的介绍及模拟】

认识哈希和unordered_set、unordered_map的介绍及模拟 哈希表基础哈希的概念哈希表的基本操作 哈希冲突哈希冲突的定义哈希冲突的影响常见的哈希冲突的解决方法 哈希函数哈希函数的定义哈希函数的设计原则常见的哈希函数 unordered系列关联式容器hash模拟 哈希表基础 哈希的概…

AI大模型大厂面试真题:「2024大厂大模型技术岗内部面试题+答案」

AI大模型岗的大厂门槛又降低了&#xff01;实在太缺人了&#xff0c;大模型岗位真的强烈建议各位多投提前批&#xff0c;▶️众所周知&#xff0c;2025届秋招提前批已经打响&#xff0c;&#x1f64b;在这里真心建议大家6月7月一定要多投提前批&#xff01; &#x1f4bb;我们…

树莓派_Opencv学习笔记23:模版样本匹配

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: ​ Opencv 版本是4.5.1&#xff1a; ​ Python 版本3.7.3&#xff1a; 今日学习Opencv样本…

MongoDB - 集合方法 db.collection.find()

文章目录 1. query 参数2. projection 参数2.1 仅返回指定的字段2.2 排除字段2.3 显式排除_id字段 3. 修改游标行为3.1 为结果集中的文档排序3.2 限制要返回的文档数量3.3 控制结果集的起点3.4 组合游标方法 db.collection.find( <query>, <projection>, <optio…

【日常记录】【插件】Typed.js:用于创建打字效果的 JavaScript 库

文章目录 1. 引言2. 安装3. 基本使用参考链接 1. 引言 Typed.js是一个用于创建打字效果的 JavaScript 库。这个效果就是 chatgpt、百度的文心一言等其他的大模型&#xff0c;回复用户的问题的时候的效果 typed-js 官网typed 案例 2. 安装 CDN方式 这俩都可以&#xff0c;还有其…

18.springboot整合swagger

springboot整合swagger 引入依赖 <!--swagger--> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version> </dependency> <dependency><groupId&…

Postman设置全部请求都携带请求头,Postman如何一次性设置请求头、不需要一个请求一个请求去添加请求头

文章目录 一、问题描述二、解决办法三、应用场景 一、问题描述 现在我有 n 个接口测试&#xff0c;其中 n 个都需要携带一致的请求头&#xff08;其实一般都是携带 JWT 令牌&#xff09;&#xff0c;怎么办&#xff1f;我要一个一个写&#xff1f;如图&#xff1a; 二、解决办…

C#从Socket里获取IP地址和端口号

在C#中&#xff0c;可以使用Socket类的RemoteEndPoint属性来获取连接的远程IP地址和端口号。以下是一个简单的示例代码&#xff0c;展示了如何从一个已连接的Socket实例中提取IP地址和端口号&#xff1a; using System; using System.Net; using System.Net.Sockets;public cl…

添加sidecar容器并输出日志

添加一个sidecar容器(使用busybox 镜像)到已有的pod 11-factor-app中,确保sidecar容器能够输出/var/log/11-factor-app.log的信息,使用volume挂载/var/log目录,确保sidecar能访问11-factor-app.log 文件 # 准备工作 创建一个 pod 11-factor-appapiVersion: v1 kind: Pod metada…