SchedulerLock LockProvider参数配置表,列,大小写等 分布式锁 定时任务锁 学习总结

一、SchedulerLock 使用场景

如果是分布式任务,即多个相同的应用执行定时任务,那么为了防止重复执行可以使用其他分布式锁做内部判断或其他形式的锁机制来防止重复执行。

SchedulerLock 提供了现成的封装好的分布式锁机制来防止定时任务被重复执行

github 官方说明:
https://github.com/lukas-krecan/ShedLock?tab=readme-ov-file

二、集成使用

1. Mave依赖 主体依赖必须添加

<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-spring</artifactId><version>5.13.0</version>
</dependency>

lockprovider 依赖,下面会说到,但根据选择不同的锁方式,依赖其实也不同,如果是其他方式请改为其他依赖

<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-jdbc-template</artifactId><version>5.13.0</version>
</dependency>

2.启用 @EnableSchedulerLock

可以直接在springBoot 启动类或者新增配置类上新增

@Configuration  // 指定为配置类  启动类上添加时 添加下面两个 这个不需要
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
class MySpringConfiguration {...
}

defaultLockAtMostFor 指定了默认的最大锁定时间,以免当前节点崩溃后其他节点拿不到锁无法继续执行

如果指定默认三十秒则可以如下

@EnableSchedulerLock(defaultLockAtMostFor = "PT30S") //默认锁的最大占有30秒

3. 在定时任务上增加该锁

import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
.......
.......@Scheduled(...)  // 任务定时
@SchedulerLock(name = "scheduledTaskName")
public void scheduledTask() {// To assert that the lock is held (prevents misconfiguration errors)LockAssert.assertLocked();// do something
}

name = “scheduledTaskName”: 为指定当前锁的名
例如

import net.javacrumbs.shedlock.core.SchedulerLock;@Scheduled(cron = "0 */15 * * * *")
@SchedulerLock(name = "scheduledTaskName", lockAtMostFor = "14m", lockAtLeastFor = "14m")
public void scheduledTask() {// do something
}

通过设置lockAtMost,我们可以确保即使节点死亡,锁也会被释放。
通过设置lockAtLeastFor,我们确保它在十五分钟内执行的次数不超过一次。

请注意,lockAtMostFor只是一个安全网,以防执行任务的节点死亡,因此请将其设置为明显大于最大估计执行时间的时间。如果任务花费的时间超过lockAtMostFor,则可能会再次执行,结果将是不可预测的(更多的进程将持有锁)。

4. 配置锁提供者 LockProvider

JdbcTemplate 方式,即通过配置一张数据库表 为此提供锁的服务,官方提供的表建表语句,如果需要其他的可以额外加入
但是基础的这些字段都必须要有,且 name 必须为主键,表名可以修改,但配置 LockProvider 时也要保持一致

# MySQL, MariaDB
CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL,locked_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name));# Postgres
CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP NOT NULL,locked_at TIMESTAMP NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name));# Oracle
CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL,locked_at TIMESTAMP(3) NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name));# MS SQL
CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until datetime2 NOT NULL,locked_at datetime2 NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name));# DB2
CREATE TABLE shedlock(name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP NOT NULL,locked_at TIMESTAMP NOT NULL, locked_by VARCHAR(255) NOT NULL);

需要的依赖,

<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-jdbc-template</artifactId><version>5.13.0</version>
</dependency>

添加该配置实体

import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
...
// 可以同步添加到上面的配置类中 也可以另开@Bean
public LockProvider lockProvider(DataSource dataSource) {return new JdbcTemplateLockProvider(JdbcTemplateLockProvider.Configuration.builder().withJdbcTemplate(new JdbcTemplate(dataSource)).usingDbTime() // Works on Postgres, MySQL, MariaDb, MS SQL, Oracle, DB2, HSQL and H2.build());
}

额外指定schema 可以直接在表名中指定:

new JdbcTemplateLockProvider(datasource, "my_schema.shedlock")

也可以存在其他配置

new JdbcTemplateLockProvider(builder().withTableName("shdlck")  // 指定表名.withColumnNames(new ColumnNames("n", "lck_untl", "lckd_at", "lckd_by"))  // 固定的四列指定为其他名字.withJdbcTemplate(new JdbcTemplate(getDatasource())) //  getDatasource() 可以封装数据源的来源 默认可以直接使用上面的 dataSource.withLockedByValue("my-value").withDbUpperCase(true)   // 大小写敏感的数据库 默认false.build())

上面 DataSource 可以通过注入的方式作为成员属性直接传入
要使用具有区分大小写的表和列名的数据库,可以使用.withDbUpperCase(true)标志。默认值为false(小写)。

import javax.sql.DataSource;
...................@AutowiredDataSource dataSource;
...................

通过指定usingDbTime(),锁提供程序将使用基于DB服务器时钟的UTC时间。如果未指定此选项,则将使用来自应用程序服务器的时钟(应用程序服务器上的时钟可能不同步,从而导致各种锁定问题)。

强烈建议使用usingDbTime()选项,因为它使用特定于数据库引擎的SQL来防止INSERT冲突。
对于更细粒度的配置,请使用configuration对象的其他选项

不要手动从DB表中删除锁定行。ShedLock有一个现有锁行的内存缓存,因此在应用程序重新启动之前不会自动重新创建该行。如果需要,您可以编辑行/文档,只需冒持有多个锁的风险。

5.使用redis 作为锁提供

使用 Spring RedisConnectionFactory

<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-redis-spring</artifactId><version>5.13.0</version>
</dependency>

配置:

import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider;
import org.springframework.data.redis.connection.RedisConnectionFactory;...@Bean
public LockProvider lockProvider(RedisConnectionFactory connectionFactory) {return new RedisLockProvider(connectionFactory, ENV);
}

使用 Spring ReactiveRedisConnectionFactory

<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-redis-spring</artifactId><version>5.13.0</version>
</dependency>
import net.javacrumbs.shedlock.provider.redis.spring.ReactiveRedisLockProvider;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;...@Bean
public LockProvider lockProvider(ReactiveRedisConnectionFactory connectionFactory) {return new ReactiveRedisLockProvider.Builder(connectionFactory).environment(ENV).build();
}

使用 Jedis

<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-redis-jedis4</artifactId><version>5.13.0</version>
</dependency>
import net.javacrumbs.shedlock.provider.redis.jedis.JedisLockProvider;...@Bean
public LockProvider lockProvider(JedisPool jedisPool) {return new JedisLockProvider(jedisPool, ENV);
}

更多支持查看官方说明
github 官方说明:
https://github.com/lukas-krecan/ShedLock?tab=readme-ov-file

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

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

相关文章

jQuery动画与特效

显示与隐藏动画 语法&#xff1a; $(obj).show(duration,fn);显示 $(obj).hide(duration,fn);隐藏 $(obj).toggle(); 功能&#xff1a; 1. show()方法能动态地改变当前元素的高度、宽度和不透明度&#xff0c;最终显示当前元素&#xff1b; 2. hide()方法会动态地改变当前元素…

AI办公自动化:多音频轨电影视频抽取出英语音频

很多电影视频是有中、英、粤语等多个音频轨的&#xff0c;如果直接转换成音频&#xff0c;很有可能不是自己想要的那种语音。 可以先查看音频流信息&#xff0c;确定属于哪个音频轨&#xff1a; Reading video file: E:\1-7\比得兔1.mp4 输出音频流信息 Available audio str…

利用viztracer进行性能分析和优化

上一篇文章&#xff0c;我们详细讲解了scalene这个性能分析和优化工具的使用流程&#xff1b;今天&#xff0c;我们将深入探讨另一个性能分析和优化工具——viztracer。 什么是viztracer&#xff1f; viztracer是一个非常强大的分析器&#xff0c;可以生成详细的性能报告和可…

设计师进阶指南:掌握这6条版式设计要点

布局设计是设计师的必修课。优秀的排版不是强制性的“东拼西凑”&#xff0c;而是通过设计师独特的排版获得的。这不是简单的信息列表&#xff0c;而是认真思考如何分层、有节奏地组织和安排元素。今天我将给你带来它 6 文章还附带了布局设计模板资源&#xff0c;设计师朋友一定…

《Windows API每日一练》6.1 鼠标基础知识

本节我们讲述鼠标的一些基础知识。 本节必须掌握的知识点&#xff1a; 鼠标 6.1.1 鼠标 鼠标是1964年由Douglas Engelbart发明的&#xff0c;用来取代由键盘输入的繁琐指令&#xff0c;简化电脑操作。早期的鼠标是单键鼠标&#xff0c;只有一个键&#xff0c;后来逐步改进为双…

EthernetIP IO从站设备数据 转opc ua项目案例

1 案例说明 设置网关采集EthernetIP IO设备数据把采集的数据转成opc ua协议转发给其他系统。 2 VFBOX网关工作原理 VFBOX网关是协议转换网关&#xff0c;是把一种协议转换成另外一种协议。网关可以采集西门子&#xff0c;欧姆龙&#xff0c;三菱&#xff0c;AB PLC&#xff0…

Element 页面滚动表头置顶

在开发后台管理系统时&#xff0c;表格是最常用的一个组件&#xff0c;为了看数据方便&#xff0c;时常需要固定表头。 如果页面基本只有一个表格区域&#xff0c;我们可以根据屏幕的高度动态的计算出一个值&#xff0c;给表格设定一个固定高度&#xff0c;这样表头就可以固定…

红酒达人教你秘技:选酒、存酒,一招一式皆学问

在繁忙的都市生活中&#xff0c;红酒不仅仅是一种饮品&#xff0c;更是一种生活态度&#xff0c;一种品味的象征。然而&#xff0c;面对琳琅满目的红酒品牌与种类&#xff0c;如何选择一瓶心仪的红酒&#xff0c;又如何妥善保存&#xff0c;使其保持很好口感&#xff0c;成为了…

python函数练习

1、编写函数&#xff0c;传入N&#xff0c;求123…N的和 def s_sum(num):i 1sum1 0while i < num:sum1 ii 1return sum1num int(input(请输入一个整数&#xff1a;)) print(和为:,s_sum(num))2、编写一个函数&#xff0c;定义一个列表&#xff0c;求列表中的最大值 d…

LabVIEW遇到无法控制国外设备时怎么办

当使用LabVIEW遇到无法控制国外产品的问题时&#xff0c;解决此类问题需要系统化的分析和处理方法。以下是详细的解决思路和具体办法&#xff0c;以及不同方法的分析和比较&#xff0c;包括寻求代理、国外技术支持、国内用过的人请教等内容。 1. 了解产品的通信接口和协议 思路…

LeetCode.25K个一组翻转链表详解

问题描述 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节…

Python 基础 (标准库):collections (集合类)

1. 官方文档 collections --- 容器数据类型 — Python 3.12.4 文档 Python 的 collections 模块提供了许多有用的数据类型&#xff08;包括 OrderedDict、Counter、defaultdict、deque 和 namedtuple&#xff09;用于扩展 Python 的标准数据类型。掌握 collections 中的数据类…

五子棋纯python手写,需要的拿去

import pygame,sys from pygame import * pygame.init()game pygame.display.set_mode((600,600)) gameover False circlebox [] # 棋盘坐标点存储 box [] def xy():for x in range(0,800//40): for y in range(0,800//40): box.append((x*40,y*40)) xy() defaultColor wh…

postman接口工具的详细使用教程

Postman 是一种功能强大的 API 测试工具&#xff0c;可以帮助开发人员和测试人员轻松地发送 HTTP 请求并分析响应。以下是对 Postman 接口测试工具的详细介绍&#xff1a; 安装与设置 安装步骤 访问 Postman 官网&#xff0c;点击右上角的“Download”按钮。 选择你的操作系统…

8.DELL R730服务器对RAID5进行扩容

如果服务器的空间不足了&#xff0c;如何进行扩容&#xff1f;我基本上按照如何重新配置虚拟磁盘或添加其他硬盘来进行操作。我的机器上已经有三块硬盘了&#xff0c;组了Raid5&#xff0c;现在再添加一块硬盘。 先把要添加的硬盘插入服务器&#xff0c;无论是在IDRAC还是管理…

leetcode153:寻找旋转排序数组中的最小值

题目链接&#xff1a;153. 寻找旋转排序数组中的最小值 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int findMin(vector<int>& nums) {int left 0, right nums.size() - 1;while(left < right){int mid left (right - left) / 2;if(nu…

物联网“此用户无权修改接入点名称设置”解决方案

根本原因apns-conf.xml里面没有 符合 物理网卡 的配置 可以先加一个APN试一下&#xff0c;看看默认的MCC和MNC是什么 然后在”命令行“查询一下 adb shell sqlite3 /data/user_de/0/com.android.providers.telephony/databases/telephony.db "select * from carriers wh…

乐鑫已支持Matter 1.2标准新增多种设备类型,启明云端乐鑫代理商

随着物联网技术的飞速发展&#xff0c;智能家居正逐渐成为现代生活的一部分。物联网和智能家居行业应用取得了巨大的增长&#xff0c;一系列无线连接的智能设备涌入家庭&#xff0c;为家庭生活带来自动化和便利。 像是可以连网的扬声器、灯泡和中控开关&#xff0c;它们都可以…

迁移学习——CycleGAN

CycleGAN 1.导入需要的包2.数据加载&#xff08;1&#xff09;to_img 函数&#xff08;2&#xff09;数据加载&#xff08;3&#xff09;图像转换 3.随机读取图像进行预处理&#xff08;1&#xff09;函数参数&#xff08;2&#xff09;数据路径&#xff08;3&#xff09;读取文…

MySQL笔记——索引

索引 SQL性能分析使用原则SQL提示覆盖索引前缀索引单列索引和联合索引索引设计原则 学习黑马MySQL课程&#xff0c;记录笔记&#xff0c;用于复习。 查询建表语句&#xff1a; show create table account;以下为建表语句&#xff1a; CREATE TABLE account (id int NOT NULL …