SpringBoot整合Quartz动态定时任务实战:零停机实现灵活调度
技术的进阶往往始于对工具边界的探索。在初识SpringBoot定时任务时,我们习惯于用@Scheduled快速实现基础调度,但当面对动态规则变更、多任务协同、故障恢复等真实场景时,这种简单方案却显得捉襟见肘。
依赖引入
properties配置
# Spring Datasource
spring.datasource.url=jdbc:mysql://192.168.10.182:13306/quartz?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Spring Quartz
spring.quartz.properties.org.quartz.scheduler.instanceName=quartz-scheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.isClustered=false
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.threadPool.threadCount=10
# Mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.quartzdemo.entity
配置类
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.annotation.Resource;
@Configuration
public class QuartzConfig {
@Resource
private SchedulerFactoryBean schedulerFactoryBean;
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean.getScheduler();
}
}
创建执行器
import
cn.hutool.core.date.DateUtil;
import
com.alibaba.fastjson2.JSON;
import org.quartz.*;
import java.util.Date;
public class ConcurrentExecutor implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 获取触发器信息
Trigger trigger = context.getTrigger();
Date startTime = trigger.getStartTime();
Date endTime = trigger.getEndTime();
System.out.println("startTime:" + DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss") + " endTime:" + DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss"));
Date previousFireTime =
trigger.getPreviousFireTime();
Date nextFireTime = trigger.getNextFireTime();
System.out.println("previousFireTime:" + DateUtil.format(previousFireTime, "yyyy-MM-dd HH:mm:ss") + " nextFireTime:" + DateUtil.format(nextFireTime, "yyyy-MM-dd HH:mm:ss"));
// 获取JobDetail信息
JobDetail jobDetail = context.getJobDetail();
// 获取JobDataMap信息
JobDataMap jobDataMap = jobDetail.getJobDataMap();
System.out.println("jobDataMap:" + JSON.toJSONString(jobDataMap));
}
}
实体类
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class InspectionJob implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 任务类型
*/
private Integer jobType;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 任务状态
*/
private Integer jobStatus;
/**
* cron表达式
*/
private String cronExpression;
/**
* 任务执行类
*/
private String clazzName;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private String createBy;
/**
* 更新时间
*/
private Date updateTime;
/**
* 更新人
*/
private String updateBy;
/**
* 删除标志
*/
private Integer deleted;
}
入参实体
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
@Data
public class InspectionJobDto implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 任务类型
*/
private Integer jobType;
/**
* 任务名称
*/
private String jobName;
/**
* cron表达式
*/
private String cronExpression;
/**
* 任务执行类
*/
private String clazzName;
/**
* 任务数据
*/
private Map
}
数据库操作
import
com.example.quartzdemo.entity.InspectionJob;
import
org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface InspectionJobMapper {
/**
* 添加任务
*
* @param data
* @return
*/
int addJob(InspectionJob data);
/**
* 更新任务
*
* @param data
* @return
*/
int updateJob(InspectionJob data);
/**
* 删除任务
*
* @param data
* @return
*/
int deleteJob(InspectionJob data);
/**
* 获取任务
*
* @param data
* @return
*/
InspectionJob getJob(InspectionJob data);
/**
* 获取所有任务
*
* @param data
* @return
*/
List
}
数据库操作xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
id,
job_name,
job_type,
cron_expression,
clazz_name,
create_time,
update_time,
create_by,
update_by,
job_status,
deleted
insert into inspection_job
(
job_name,
job_type,
cron_expression,
clazz_name,
create_time,
update_time,
create_by,
update_by,
job_status
)
values
(
#{jobName},
#{jobType},
#{cronExpression},
#{clazzName},
now(),
now(),
#{createBy},
#{updateBy},
#{jobStatus}
)
update inspection_job
<set>
job_name = #{jobName},
job_type = #{jobType},
cron_expression = #{cronExpression},
clazz_name = #{clazzName},
job_status = #{jobStatus},
create_time = #{createTime},
update_time = #{updateTime},
create_by = #{createBy},
update_by = #{updateBy},
</set>
where deleted = 0 AND id = #{id}
update inspection_job
set deleted = 1,
update_time = now(),
update_by = #{updateBy}
where deleted = 0 AND id = #{id}
任务服务接口
import
com.example.quartzdemo.entity.InspectionJob;
import
com.example.quartzdemo.entity.InspectionJobDto;
import java.util.List;
public interface InspectionJobService {
/**
* 添加定时任务Job
*
*/
void addJob(InspectionJobDto dto);
/**
* 立即执行一次定时任务
*
*/
void executeOnce(InspectionJobDto dto);
/**
* 暂停定时任务
*
*/
void pauseJob(InspectionJobDto dto);
/**
* 恢复定时任务
*
*/
void resumeJob(InspectionJobDto dto);
/**
* 更新定时任务
*
*/
void updateJob(InspectionJobDto dto);
/**
* 删除定时任务
*
*/
void deleteJob(InspectionJobDto dto);
/**
* 获取所有的定时任务*
* @return 定时任务列表
*/
List
}
任务服务实现
import
com.example.quartzdemo.constant.QuartzConstant;
import
com.example.quartzdemo.constant.QuartzCron;
import
com.example.quartzdemo.constant.QuartzJobStatus;
import
com.example.quartzdemo.entity.InspectionJob;
import
com.example.quartzdemo.entity.InspectionJobDto;
import
com.example.quartzdemo.executor.ConcurrentExecutor;
import
com.example.quartzdemo.mapper.InspectionJobMapper;
import
com.example.quartzdemo.service.InspectionJobService;
import
lombok.RequiredArgsConstructor;
import org.quartz.*;
import
org.springframework.beans.BeanUtils;
import
org.springframework.stereotype.Service;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class InspectionJobServiceImpl implements InspectionJobService {
private final InspectionJobMapper inspectionJobMapper;
private final Scheduler scheduler;
@Override
public void addJob(InspectionJobDto dto) {
InspectionJob inspectionJob = new InspectionJob();
BeanUtils.copyProperties(dto, inspectionJob);
inspectionJob.setJobStatus(
QuartzJobStatus.RUNNING.getCode());
inspectionJobMapper.addJob(inspectionJob);
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, inspectionJob.getId()), QuartzConstant.JOB_GROUP);
try {
Integer jobType = inspectionJob.getJobType();
QuartzCron quartzCron = QuartzCron.getCron(jobType);
Map
JobBuilder jobBuilder = JobBuilder.newJob(quartzCron.getClazz());
if (params != null){
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.putAll(params);
jobBuilder.usingJobData(jobDataMap);
}
jobBuilder.withIdentity(jobKey);
JobDetail jobDetail = jobBuilder.build();
TriggerKey triggerKey = TriggerKey.triggerKey(String.format("%s_%s",
QuartzConstant.TRIGGER_NAME, inspectionJob.getId()),
QuartzConstant.TRIGGER_GROUP);
TriggerBuilder
triggerBuilder.withIdentity(triggerKey);
triggerBuilder.withSchedule(
CronScheduleBuilder.cronSchedule(quartzCron.getCron()));
triggerBuilder.startNow();
Trigger trigger = triggerBuilder.build();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("任务创建失败");
}
}
@Override
public void executeOnce(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("执行一次失败");
}
}
@Override
public void pauseJob(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.pauseJob(jobKey);
InspectionJob inspectionJob = new InspectionJob();
inspectionJob.setId(dto.getId());
inspectionJob.setJobStatus(
QuartzJobStatus.PAUSED.getCode());
inspectionJob.setUpdateBy("test");
inspectionJob.setUpdateTime(new Date());
inspectionJobMapper.updateJob(inspectionJob);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("暂停任务失败");
}
}
@Override
public void resumeJob(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.resumeJob(jobKey);
InspectionJob inspectionJob = new InspectionJob();
inspectionJob.setId(dto.getId());
inspectionJob.setJobStatus(
QuartzJobStatus.RUNNING.getCode());
inspectionJob.setUpdateBy("test");
inspectionJob.setUpdateTime(new Date());
inspectionJobMapper.updateJob(inspectionJob);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("恢复任务失败");
}
}
@Override
public void updateJob(InspectionJobDto dto) {
}
@Override
public void deleteJob(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.deleteJob(jobKey);
InspectionJob inspectionJob = new InspectionJob();
inspectionJob.setId(dto.getId());
inspectionJob.setUpdateBy("test");
inspectionJob.setUpdateTime(new Date());
inspectionJobMapper.deleteJob(inspectionJob);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("删除任务失败");
}
}
@Override
public List
return null;
}
}
常量信息
public interface QuartzConstant {
String JOB_NAME = "jobName";
String JOB_GROUP = "jobGroup";
String TRIGGER_NAME = "triggerName";
String TRIGGER_GROUP = "triggerGroup";
}
import
com.example.quartzdemo.executor.ConcurrentExecutor;
import lombok.Getter;
import org.quartz.Job;
import java.util.HashMap;
import java.util.Map;
@Getter
public enum QuartzCron {
/**
* 一年一次
*/
YEARLY(0,"0 0 0 1 1 ? *",ConcurrentExecutor.class),
/**
* 每季度一次
*/
QUARTERLY(1,"0 0 0 1 1/3 ? *",ConcurrentExecutor.class),
/**
* 每月一次
*/
MONTHLY(2,"0 0 0 1 * ? *",ConcurrentExecutor.class),
/**
* 每周一次
*/
WEEKLY(3,"0 0 0 ? * 1 *",ConcurrentExecutor.class),
/**
* 每日一次
*/
DAILY(4,"0 0 0 * * ? *",ConcurrentExecutor.class),
/**
* 每小时一次
*/
HOURLY(5,"0 0 0/1 * * ? *",ConcurrentExecutor.class),
/**
* 每分钟一次
*/
MINUTE(6,"0 0/1 * * * ? *", ConcurrentExecutor.class);
/**
* 枚举值
*/
private final Integer code;
/**
* 描述
*/
private final String cron;
/**
* 执行器
*/
private final Class extends job> clazz;
private static final Map
QuartzCron(Integer code, String cron,Class extends job> clazz) {
this.code = code;
this.cron = cron;
this.clazz = clazz;
}
static {
for (QuartzCron quartzCron : QuartzCron.values()) {
cronMap.put(quartzCron.getCode(),quartzCron);
}
}
public static QuartzCron getCron(Integer code) {
return cronMap.get(code);
}
}
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
@Getter
public enum QuartzJobStatus {
NORMAL(0,"待执行"),
RUNNING(1,"运行中"),
PAUSED(2,"已暂停"),
COMPLETE(3,"已完成"),
;
private final Integer code;
private final String desc;
private static final Map
static {
for (QuartzJobStatus status : QuartzJobStatus.values()) {
statusMap.put(status.getCode(),status);
}
}
QuartzJobStatus(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
}
Controller层
import com.example.quartzdemo.entity.InspectionJobDto;
import com.example.quartzdemo.service.InspectionJobService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@RequestMapping("/job")
public class InspectionJobController {
private final InspectionJobService inspectionJobService;
@PostMapping("/add")
public void addJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.addJob(dto);
}
@PostMapping("/executeOnce")
public void executeOnce(@RequestBody InspectionJobDto dto)
{
inspectionJobService.executeOnce(dto);
}
@PostMapping("/pause")
public void pauseJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.pauseJob(dto);
}
@PostMapping("/resume")
public void resumeJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.resumeJob(dto);
}
@PostMapping("/update")
public void updateJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.updateJob(dto);
}
@PostMapping("/delete")
public void deleteJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.deleteJob(dto);
}
@PostMapping("/getAll")
public Object getAllJob()
{
return inspectionJobService.getAllJob();
}
}
表结构
--
----------------------------
-- Table structure for inspection_job
--
----------------------------
DROP TABLE IF EXISTS `inspection_job`;
CREATE TABLE `inspection_job` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`job_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`job_type` int NULL DEFAULT NULL COMMENT '任务类型(0:一年一次,1:一季度一次,2:一月一次,3:一周一次)',
`cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'cron表达式',
`clazz_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '执行器全路径名',
`city_id` bigint NULL DEFAULT NULL,
`district_id` bigint NULL DEFAULT NULL,
`street_id` bigint NULL DEFAULT NULL,
`job_status` int NULL DEFAULT NULL COMMENT '任务状态(0:待执行,1:运行中,2:已暂停,3:已完成)',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
`create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`deleted` int NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_BLOB_TRIGGERS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`BLOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `SCHED_NAME`(`SCHED_NAME` ASC, `TRIGGER_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE,
CONSTRAINT `QRTZ_BLOB_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_CALENDARS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
CREATE TABLE `QRTZ_CALENDARS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`CALENDAR_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`CALENDAR` blob NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_CRON_TRIGGERS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
CREATE TABLE `QRTZ_CRON_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`CRON_EXPRESSION` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TIME_ZONE_ID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `QRTZ_CRON_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_FIRED_TRIGGERS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`ENTRY_ID` varchar(95) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`INSTANCE_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`FIRED_TIME` bigint NOT NULL,
`SCHED_TIME` bigint NOT NULL,
`PRIORITY` int NOT NULL,
`STATE` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`JOB_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `ENTRY_ID`) USING BTREE,
INDEX `
IDX_QRTZ_FT_TRIG_INST_NAME`(`SCHED_NAME` ASC, `INSTANCE_NAME` ASC) USING BTREE,
INDEX `
IDX_QRTZ_FT_INST_JOB_REQ_RCVRY`(`SCHED_NAME` ASC, `INSTANCE_NAME` ASC, `REQUESTS_RECOVERY` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_J_G`(`SCHED_NAME` ASC, `JOB_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_JG`(`SCHED_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_T_G`(`SCHED_NAME` ASC, `TRIGGER_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_TG`(`SCHED_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_JOB_DETAILS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
CREATE TABLE `QRTZ_JOB_DETAILS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`DESCRIPTION` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`JOB_CLASS_NAME` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`IS_DURABLE` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`IS_UPDATE_DATA` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_J_REQ_RECOVERY`(`SCHED_NAME` ASC, `REQUESTS_RECOVERY` ASC) USING BTREE,
INDEX `IDX_QRTZ_J_GRP`(`SCHED_NAME` ASC, `JOB_GROUP` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_LOCKS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_LOCKS`;
CREATE TABLE `QRTZ_LOCKS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`LOCK_NAME` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `LOCK_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_PAUSED_TRIGGER_GRPS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_SCHEDULER_STATE
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
CREATE TABLE `QRTZ_SCHEDULER_STATE` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`INSTANCE_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`LAST_CHECKIN_TIME` bigint NOT NULL,
`CHECKIN_INTERVAL` bigint NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_SIMPLE_TRIGGERS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`REPEAT_COUNT` bigint NOT NULL,
`REPEAT_INTERVAL` bigint NOT NULL,
`TIMES_TRIGGERED` bigint NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `
QRTZ_SIMPLE_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_SIMPROP_TRIGGERS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`STR_PROP_1` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`STR_PROP_2` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`STR_PROP_3` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`INT_PROP_1` int NULL DEFAULT NULL,
`INT_PROP_2` int NULL DEFAULT NULL,
`LONG_PROP_1` bigint NULL DEFAULT NULL,
`LONG_PROP_2` bigint NULL DEFAULT NULL,
`DEC_PROP_1` decimal(13, 4) NULL DEFAULT NULL,
`DEC_PROP_2` decimal(13, 4) NULL DEFAULT NULL,
`BOOL_PROP_1` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`BOOL_PROP_2` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `
QRTZ_SIMPROP_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
--
----------------------------
-- Table structure for QRTZ_TRIGGERS
--
----------------------------
DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
CREATE TABLE `QRTZ_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`DESCRIPTION` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`NEXT_FIRE_TIME` bigint NULL DEFAULT NULL,
`PREV_FIRE_TIME` bigint NULL DEFAULT NULL,
`PRIORITY` int NULL DEFAULT NULL,
`TRIGGER_STATE` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_TYPE` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`START_TIME` bigint NOT NULL,
`END_TIME` bigint NULL DEFAULT NULL,
`CALENDAR_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`MISFIRE_INSTR` smallint NULL DEFAULT NULL,
`JOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_T_J`(`SCHED_NAME` ASC, `JOB_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_JG`(`SCHED_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_C`(`SCHED_NAME` ASC, `CALENDAR_NAME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_G`(`SCHED_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_STATE`(`SCHED_NAME` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_N_STATE`(`SCHED_NAME` ASC, `TRIGGER_NAME` ASC, `TRIGGER_GROUP` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_N_G_STATE`(`SCHED_NAME` ASC, `TRIGGER_GROUP` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NEXT_FIRE_TIME`(`SCHED_NAME` ASC, `NEXT_FIRE_TIME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST`(`SCHED_NAME` ASC, `TRIGGER_STATE` ASC, `NEXT_FIRE_TIME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_MISFIRE`(`SCHED_NAME` ASC, `MISFIRE_INSTR` ASC, `NEXT_FIRE_TIME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE`(`SCHED_NAME` ASC, `MISFIRE_INSTR` ASC, `NEXT_FIRE_TIME` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `
IDX_QRTZ_T_NFT_ST_MISFIRE_GRP`(`SCHED_NAME` ASC, `MISFIRE_INSTR` ASC, `NEXT_FIRE_TIME` ASC, `TRIGGER_GROUP` ASC, `TRIGGER_STATE` ASC) USING BTREE,
CONSTRAINT `QRTZ_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;