第一步:引入shedlock相关依赖
<!--集成shedlock解决定时任务重复执行的问题-->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>2.2.1</version>
</dependency>
ShedLock还可以使用Mongo,Redis,Hazelcast,ZooKeeper等外部存储进行协调,例如使用redis则引入下面的包
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-redis-spring</artifactId>
<version>${shedlock.redis.version}</version>
</dependency>
第二步:创建数据库表结构,数据库表的脚本如下:
CREATE TABLE shedlock(
NAME VARCHAR(64),
lock_until TIMESTAMP(3) NULL,
locked_at TIMESTAMP(3) NULL,
locked_by VARCHAR(255),
PRIMARY KEY (NAME)
)
第三步:添加shedlock配置类(定时任务防重复执行的配置类)
package com.sionma.dcxt.config;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.ScheduledLockConfiguration;
import net.javacrumbs.shedlock.spring.ScheduledLockConfigurationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import javax.sql.DataSource;
import java.time.Duration;
/**
* FileName: ShedlockConfig
* Author: SixJR.
* Date: 2023/6/23 21:26:24
* Description: 定时任务防重复执行的配置类
* History:
* <author> <time> <version> <desc>
*/
@Configuration
@EnableScheduling
public class ShedlockConfig {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
@Bean
public ScheduledLockConfiguration scheduledLockConfiguration(LockProvider lockProvider) {
return ScheduledLockConfigurationBuilder
.withLockProvider(lockProvider)
.withPoolSize(10)
.withDefaultLockAtMostFor(Duration.ofMinutes(10))
.build();
}
}
第四步:在启动类上添加启动注解,否则SchedulerLock不会生效
@EnableSchedulerLock(defaultLockAtMostFor = "PT50S")
第五步:在执行定时任务的方法上面加上你要限制重复执行的注解@SchedulerLock
// 锁最多保持50秒,最少保持40秒
@SchedulerLock(name = "orderCancelTask", lockAtMostFor = 50 * 1000, lockAtLeastFor = 40 * 1000)
以下是该注解的属性解释:
@SchedulerLock注解是Quartz Scheduler中的一个扩展注解,用于控制定时任务的并发执行。该注解具有以下属性:
name:设置任务的名称。该名称用于标识任务,在Quartz Scheduler中唯一。通常建议为任务命名一个具有描述性的名称。
lockAtMostFor:设置任务的最长锁定时间。这个值表示任务的最长允许运行时间。如果任务在此时间段内未能执行完成,Quartz Scheduler将会中断任务运行。属性值是以毫秒为单位的长整数。
lockAtLeastFor:设置任务的最短锁定时间。这个值表示任务被锁定的最短时间。即使任务的业务逻辑执行时间很短,也会保持锁定指定的时间。属性值是以毫秒为单位的长整数。