Quartz使用文档
前两天刚刚学习了一波Quartz怎么使用,单机实现quartz其实并不难,只需要任务实现类+调度器配置类+任务工厂类,调度器工厂配置的properties文件中中IsCluster的值设为false就行了。事实上,如果你只需要单机定时任务的话,在定时任务的方法前加一个spring自带的@Scheduled("cron表达式")注解就行了,轻量便捷可用性高,完全没有必要引入一个新包,不过记得在启动器前加一个@EnableScheduled注解使这个注解能被扫描到。现在开始讲的是集群环境下的Quartz的使用。
一、引用依赖
<!--quartz start-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<!--quartz end-->
第一个实现定时任务,第二个引入了集群化的相关包,第三个是为了实现job内自动注入
二、Quartz集群化的基本原理:
Quartz实现集群化的原理其实很简单,它其实是通过将任务、触发器等持久化到数据库中,通过对触发器上锁来实现多服务器下只触发一次的功能的,不过好的地方在于,当你建好了表配置好了DataSource,Quartz并不需要你给予数据库太多的关注,甚至可以假装它不存在。
当你进行schedule的时候,任务和触发器会一并存入数据库,而当你下一次从工厂类中取出schedule的时候,工厂类会自动扫描库中仍然活跃的任务和触发器,将它们置入schedule中再给你,所以如果你的业务很多,在我的结构的基础上另写一个QuartzJobManager接口+服务会更适合你。
三、基本结构——三类一配置一库
三类:调度器配置类、任务工厂类、任务实现类
一配置:储存调度器配置类中调度器工厂类配置的properties文件。
一库:持久化需要的数据库。
注:数据库不在java项目的体系内故为画在图上,数据库需要另建。
1.三类——调度器配置类、任务工厂类、任务实现类:
1.1任务实现类:
public class RepairRepairJob extends QuartzJobBean {
Logger logger = LoggerFactory.getLogger(RepairRepairJob.class);
@Autowired
LenkingService lenkingService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) {
lenkingService.createAndSendReport();
logger.info("Service has done.");
}
}
类如其名,在这里可以像服务实现类一样注入服务实现业务逻辑,但现在还只是个花瓶,因为它不在自动注入体系内,在有了任务工厂类之后就和Service实现类没什么区别了。
另,这里不一定要集成QuartzJobBean这个类,实现Quartz包中的Job也可以,业务都写在必须实现的形如executeXxx…的方法中。
1.2任务工厂类:
@Component
public class JobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
就是一个工具类,存在的意义是在这个类中将任务实现类放入springboot的自动注入体系中。job在quartz体系中是不会被springboot发现并注入的,只有通过工厂类配置手动连接才行。这个类基本只需要复制就行,就是一个工具类,基本不需要动。
1.3调度器配置类:
这个类中主要有两个方法,调度器工厂的配置方法和调度器的配置方法。
调度器工厂配置方法:
@Autowired
private JobFactory jobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//TODO 设置是否覆盖已有任务(但是我试的时候该报错还是得报错)
factory.setOverwriteExistingJobs(true);
//TODO 引入自动注入的任务工厂,否则任务无法使用需要自动注入的服务
factory.setJobFactory(jobFactory);
// TODO 导入其他配置
factory.setConfigLocation(new ClassPathResource("/quartz/quartz.properties"));
return factory;
}
工厂配置方法只有两个配置是最关键的,一个是引入自动注入的任务工厂,事关任务中的服务能否自动注入,一个是导入配置方法,有关数据源,持久化还有集群都在这个配置文件里,有关配置文件后面会讲。
调度器配置方法:
@Value("${order.report.sendMail.cron}")
private String cron;
private String triggerName = "repairReportTrigger";
private String groupName = "repairReportGroup";
private String jobName = "repairReportJob";
@Bean
public Scheduler scheduler() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean().getScheduler();
// TODO 把上一次的任务给删除了,否则程序会根据数据库里的trigger信息自动判断并执行项目关闭期间未执行的任务
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, groupName);
scheduler.unscheduleJob(triggerKey);
// TODO 重新把任务和触发器给放入调度器中
JobDetail job = JobBuilder.newJob(RepairRepairJob.class)
.withIdentity(jobName, groupName)
.build();
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerName, groupName)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
scheduler.scheduleJob(job, trigger);
// TODO 如果调度器没有启动则将调度器启动起来
if (!scheduler.isStarted()) {
scheduler.start();
}
return scheduler;
}
调度器方法最基本的功能是,从调度器工厂内拿出调度器并作为一个Bean返回,如果你的业务逻辑简单,可以在返回调度器之前往调度器内增加任务和触发器;如果业务逻辑复杂,并且要实现线上动态开关定时任务之类的功能,那么可以在此处返回调度器,在工具包里另加一个QuartzManager类,自动注入调度器,并对其进行操作。
给一个调度器配置类的demo
@Configuration
public class QuartzConfig {
@Autowired
private JobFactory jobFactory;
@Value("${report.sendMail.cron}")//可以不用@Value直接赋值
private String cron;
private String triggerName = "reportTrigger";
private String groupName = "reportGroup";
private String jobName = "reportJob";
@Bean
public Scheduler scheduler() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean().getScheduler();
// TODO 把上一次的任务给删除了,否则程序会根据数据库里的trigger信息自动判断并执行项目关闭期间未执行的任务
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, groupName);
scheduler.unscheduleJob(triggerKey);
// TODO 重新把任务和触发器给放入调度器中
JobDetail job = JobBuilder.newJob(RepairRepairJob.class)
.withIdentity(jobName, groupName)
.build();
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerName, groupName)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
scheduler.scheduleJob(job, trigger);
// TODO 如果调度器没有启动则将调度器启动起来
if (!scheduler.isStarted()) {
scheduler.start();
}
return scheduler;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//TODO 设置是否覆盖已有任务(但是我试的时候该报错还是得报错)
factory.setOverwriteExistingJobs(true);
//TODO 引入自动注入的任务工厂,否则任务无法使用需要自动注入的服务
factory.setJobFactory(jobFactory);
// TODO 如果有已配置好的数据源可以自动注入后添加入factory配置
// factory.setDatasource(datasource)
// TODO 导入其他配置
factory.setConfigLocation(new ClassPathResource("/quartz/quartz.properties"));
return factory;
}
}
最后是一配置,配置文件是给调度器配置类中调度器配置方法输入配置的,早前都是用Propertis类来一个个键入的,现在能简化成从properties文件读取,已经很不错了。具体就是新建一个连接,把键值对放进去。
这一部分请参考链接:https://blog.csdn.net/wusandi/article/details/78324220
这里也给个Demo
#Scheduler相关属性配置-----------------------
org.quartz.scheduler.instanceName=QuartzScheduler
#配置节点名称的调度器名称,每个节点必须不同,AUTO能自动为本节点命名
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.skipUpdateCheck=true
#线程池相关属性配置---------------------------
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority=5
#SimpleThreadPool的特定属性
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#如果要设置自定义的线程池则按照这个格式
#org.quartz.threadPool.class = com.mycompany.goo.FooThreadPool
#org.quartz.threadPool.somePropOfFooThreadPool = someValue
#配置插件------------------------------------
org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin
#关闭钩子存在导致项目不能正常关闭的问题故暂不加入,我还未解决这个问题,可能你那是好的
#org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
#org.quartz.plugin.shutdownhook.cleanShutdown = true
#JobStore的相关属性配置,JobStore是任务储存的需要用的类-------------------
#允许jobStore与jobDataMaps中以键值对的形式储存值防止大字段blob的出现
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix=T_B_QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#触发器失败后下一次尝试的时间间隔
org.quartz.jobStore.misfireThreshold=60000
#设置当前实例检测集群中其它实例的频率,影响检测到故障实例的速度
org.quartz.jobStore.clusterCheckinInterval=20000
#处理失败trigger的最大等待时间,防止出现死锁或是处理时间过长导致其它trigger的性能受限
org.quartz.jobStore.maxMisfiresToHandleAtATime=0
org.quartz.jobStore.selectWithLockSQL=SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE
#配置DataSource
#数据源别名,随便起,下面和它相匹配就行
org.quartz.jobStore.dataSource=quartzDS
org.quartz.dataSource.quartzDS.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.quartzDS.URL=jdbc:mysql://localhost:3306/quartz?useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useAffectedRows=true
org.quartz.dataSource.quartzDS.user=root
org.quartz.dataSource.quartzDS.password=123456
org.quartz.dataSource.quartzDS.maxConnections=10
以上,只是个样例,你可以按照自己的需求配置,如果你有已经配置好的数据源,那可以在调度器工厂类的配置方法中set进去,这里就不需要对数据源进行配置了。
最后就是对数据库的配置了
你可以使用下面这段SQL语句,表前缀可以更改,注意配合配置文件中的org.quartz.jobStore.tablePrefix这一项。
在你复制之前我要提醒你一点,请一定注意,因为可能会导致出现莫名的bug,那就是,在别人的文章里,sql可能会出现小写的表名、列名,如果你用的是数据库在windows系统或者mac OS系统,那没问题,但如果是在linux系统,则会出错,因为linux区分大小写,如果你使用小写表名quartz会识别不出表,也识别不到列。
DROP TABLE
IF
EXISTS T_B_QRTZ_FIRED_TRIGGERS;
DROP TABLE
IF
EXISTS T_B_QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE
IF
EXISTS T_B_QRTZ_SCHEDULER_STATE;
DROP TABLE
IF
EXISTS T_B_QRTZ_LOCKS;
DROP TABLE
IF
EXISTS T_B_QRTZ_SIMPLE_TRIGGERS;
DROP TABLE
IF
EXISTS T_B_QRTZ_SIMPROP_TRIGGERS;
DROP TABLE
IF
EXISTS T_B_QRTZ_CRON_TRIGGERS;
DROP TABLE
IF
EXISTS T_B_QRTZ_BLOB_TRIGGERS;
DROP TABLE
IF
EXISTS T_B_QRTZ_TRIGGERS;
DROP TABLE
IF
EXISTS T_B_QRTZ_JOB_DETAILS;
DROP TABLE
IF
EXISTS T_B_QRTZ_CALENDARS;
CREATE TABLE T_B_QRTZ_JOB_DETAILS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
JOB_NAME VARCHAR ( 200 ) NOT NULL,
JOB_GROUP VARCHAR ( 200 ) NOT NULL,
DESCRIPTION VARCHAR ( 250 ) NULL,
JOB_CLASS_NAME VARCHAR ( 250 ) NOT NULL,
IS_DURABLE VARCHAR ( 1 ) NOT NULL,
IS_NONCONCURRENT VARCHAR ( 1 ) NOT NULL,
IS_UPDATE_DATA VARCHAR ( 1 ) NOT NULL,
REQUESTS_RECOVERY VARCHAR ( 1 ) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY ( SCHED_NAME, JOB_NAME, JOB_GROUP )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_TRIGGERS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
TRIGGER_NAME VARCHAR ( 200 ) NOT NULL,
TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL,
JOB_NAME VARCHAR ( 200 ) NOT NULL,
JOB_GROUP VARCHAR ( 200 ) NOT NULL,
DESCRIPTION VARCHAR ( 250 ) NULL,
NEXT_FIRE_TIME BIGINT ( 13 ) NULL,
PREV_FIRE_TIME BIGINT ( 13 ) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR ( 16 ) NOT NULL,
TRIGGER_TYPE VARCHAR ( 8 ) NOT NULL,
START_TIME BIGINT ( 13 ) NOT NULL,
END_TIME BIGINT ( 13 ) NULL,
CALENDAR_NAME VARCHAR ( 200 ) NULL,
MISFIRE_INSTR SMALLINT ( 2 ) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ),
FOREIGN KEY ( SCHED_NAME, JOB_NAME, JOB_GROUP ) REFERENCES T_B_QRTZ_JOB_DETAILS ( SCHED_NAME, JOB_NAME, JOB_GROUP )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
TRIGGER_NAME VARCHAR ( 200 ) NOT NULL,
TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL,
REPEAT_COUNT BIGINT ( 7 ) NOT NULL,
REPEAT_INTERVAL BIGINT ( 12 ) NOT NULL,
TIMES_TRIGGERED BIGINT ( 10 ) NOT NULL,
PRIMARY KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ),
FOREIGN KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ) REFERENCES T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
TRIGGER_NAME VARCHAR ( 200 ) NOT NULL,
TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL,
CRON_EXPRESSION VARCHAR ( 120 ) NOT NULL,
TIME_ZONE_ID VARCHAR ( 80 ),
PRIMARY KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ),
FOREIGN KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ) REFERENCES T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_SIMPROP_TRIGGERS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
TRIGGER_NAME VARCHAR ( 200 ) NOT NULL,
TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL,
STR_PROP_1 VARCHAR ( 512 ) NULL,
STR_PROP_2 VARCHAR ( 512 ) NULL,
STR_PROP_3 VARCHAR ( 512 ) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC ( 13, 4 ) NULL,
DEC_PROP_2 NUMERIC ( 13, 4 ) NULL,
BOOL_PROP_1 VARCHAR ( 1 ) NULL,
BOOL_PROP_2 VARCHAR ( 1 ) NULL,
PRIMARY KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ),
FOREIGN KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ) REFERENCES T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
TRIGGER_NAME VARCHAR ( 200 ) NOT NULL,
TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ),
INDEX ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ),
FOREIGN KEY ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP ) REFERENCES T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_CALENDARS ( SCHED_NAME VARCHAR ( 120 ) NOT NULL, CALENDAR_NAME VARCHAR ( 200 ) NOT NULL, CALENDAR BLOB NOT NULL, PRIMARY KEY ( SCHED_NAME, CALENDAR_NAME ) ) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_PAUSED_TRIGGER_GRPS ( SCHED_NAME VARCHAR ( 120 ) NOT NULL, TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL, PRIMARY KEY ( SCHED_NAME, TRIGGER_GROUP ) ) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
ENTRY_ID VARCHAR ( 95 ) NOT NULL,
TRIGGER_NAME VARCHAR ( 200 ) NOT NULL,
TRIGGER_GROUP VARCHAR ( 200 ) NOT NULL,
INSTANCE_NAME VARCHAR ( 200 ) NOT NULL,
FIRED_TIME BIGINT ( 13 ) NOT NULL,
SCHED_TIME BIGINT ( 13 ) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR ( 16 ) NOT NULL,
JOB_NAME VARCHAR ( 200 ) NULL,
JOB_GROUP VARCHAR ( 200 ) NULL,
IS_NONCONCURRENT VARCHAR ( 1 ) NULL,
REQUESTS_RECOVERY VARCHAR ( 1 ) NULL,
PRIMARY KEY ( SCHED_NAME, ENTRY_ID )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR ( 120 ) NOT NULL,
INSTANCE_NAME VARCHAR ( 200 ) NOT NULL,
LAST_CHECKIN_TIME BIGINT ( 13 ) NOT NULL,
CHECKIN_INTERVAL BIGINT ( 13 ) NOT NULL,
PRIMARY KEY ( SCHED_NAME, INSTANCE_NAME )
) ENGINE = INNODB;
CREATE TABLE T_B_QRTZ_LOCKS ( SCHED_NAME VARCHAR ( 120 ) NOT NULL, LOCK_NAME VARCHAR ( 40 ) NOT NULL, PRIMARY KEY ( SCHED_NAME, LOCK_NAME ) ) ENGINE = INNODB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON T_B_QRTZ_JOB_DETAIL ( SCHED_NAME, REQUESTS_RECOVERY );
CREATE INDEX IDX_QRTZ_J_GRP ON T_B_QRTZ_JOB_DETAILS ( SCHED_NAME, JOB_GROUP );
CREATE INDEX IDX_QRTZ_T_J ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, JOB_NAME, JOB_GROUP );
CREATE INDEX IDX_QRTZ_T_JG ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, JOB_GROUP );
CREATE INDEX IDX_QRTZ_T_C ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, CALENDAR_NAME );
CREATE INDEX IDX_QRTZ_T_G ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_GROUP );
CREATE INDEX IDX_QRTZ_T_STATE ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_STATE );
CREATE INDEX IDX_QRTZ_T_N_STATE ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, TRIGGER_STATE );
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_GROUP, TRIGGER_STATE );
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, NEXT_FIRE_TIME );
CREATE INDEX IDX_QRTZ_T_NFT_ST ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, TRIGGER_STATE, NEXT_FIRE_TIME );
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME );
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_STATE );
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON T_B_QRTZ_TRIGGERS ( SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_GROUP, TRIGGER_STATE );
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON T_B_QRTZ_FIRED_TRIGGERS ( SCHED_NAME, INSTANCE_NAME );
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON T_B_QRTZ_FIRED_TRIGGERS ( SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY );
CREATE INDEX IDX_QRTZ_FT_J_G ON T_B_QRTZ_FIRED_TRIGGERS ( SCHED_NAME, JOB_NAME, JOB_GROUP );
CREATE INDEX IDX_QRTZ_FT_JG ON T_B_QRTZ_FIRED_TRIGGERS ( SCHED_NAME, JOB_GROUP );
CREATE INDEX IDX_QRTZ_FT_T_G ON T_B_QRTZ_FIRED_TRIGGERS ( SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP );
CREATE INDEX IDX_QRTZ_FT_TG ON T_B_QRTZ_FIRED_TRIGGERS ( SCHED_NAME, TRIGGER_GROUP );
至此,quartz应该是配置完成了,如果你要拿去使用这些代码应该也能直接拿去用了。
如果你是一个企业用户,那么可能会有多个项目 需要使用quartz,在这种情况下,建议建立一个quartz的独立数据库,通过前缀区分项目任务表(这就是前缀存在的意义)。
如果你觉得一个个改sql语句中的表前缀太麻烦了,可以下载我的数据库储存过程,但是这个东西写的我非常糟心,所以是收费的。需要下载可以跳转https://download.csdn.net/download/weixin_41263382/11002891。