使用shedlock实现分布式定时任务锁【防止task定时任务重复执行】

第一步:引入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:设置任务的最短锁定时间。这个值表示任务被锁定的最短时间。即使任务的业务逻辑执行时间很短,也会保持锁定指定的时间。属性值是以毫秒为单位的长整数。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_43413873/article/details/131355346