前言
工作中需要在调度中加入分布式锁,通过shedlock表中插入同一个name(primary key),或者更新同一个name来抢锁
一、引入包
<!--springboot 调度加锁 -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.19.1</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>4.19.1</version>
</dependency>
二、添加数据库表
CREATE TABLE shedlock(
NAME VARCHAR2(64),
lock_until TIMESTAMP(3) NULL,
locked_at TIMESTAMP(3) NULL,
locked_by VARCHAR(255),
PRIMARY KEY (NAME)
)
三、添加ShedLockConfig
import java.util.TimeZone;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
@Configuration
public class ShedLockConfig {
@Bean
public LockProvider lockProvider(final DataSource dataSource) {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withJdbcTemplate(new JdbcTemplate(dataSource))
.withTimeZone(TimeZone.getTimeZone("GMT+8")) // 使用下面usingDbTime ,表中展示的时间不对
//.usingDbTime() // Works on Postgres, MySQL, MariaDb, MS SQL, Oracle, DB2, HSQL and H2
.build()
);
}
}
四、调度类加注解
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
@Component
public class Scheduler {
/**
* 配置调度使用 .
* 0 0 0,8,12,18 * * ? -----每天0,8,12,18点执行 .
* 0 0 * * * ? -----每个整点执行 .
* 0 0(*)/1 * * * ? -----每分钟执行 .
* 0(*)/10 * * * * ? -----每10秒执行 .
*/
@Scheduled(cron = "${jobs.main.cron}")
@SchedulerLock(name = "test", lockAtMostFor = "60s", lockAtLeastFor = "10s") // 锁最多保持60秒,最少保持10秒
public void testJob() {
//执行调度
}
}
五、启动类加注解
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT50S")