Spring+Quartz定时任务集群环境下部署的解决方法

1、配置quartz.properties文件,如下
#==========================================================================

Configure Main Scheduler Properties

#=========================================================================
org.quartz.scheduler.instanceName: ClusterScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler.skipUpdateCheck: true
#==========================================================================

Configure ThreadPool

#==========================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 20
org.quartz.threadPool.threadPriority: 5
#==========================================================================

Configure JobStore

#==========================================================================
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true

#=========================================================================

Configure Datasources

#==========================================================================

org.quartz.dataSource.myDS.driver: net.sourceforge.jtds.jdbc.Driver
org.quartz.dataSource.myDS.URL: amRiYzpqdGRzOnNxbHNlcnZlcjovL2xvY2FsaG9zdDoxNDMzO0RhdGFiYXNlTmFtZT1jaWNz
org.quartz.dataSource.myDS.user: Y2ljcw==
org.quartz.dataSource.myDS.password: Y2ljcw==
org.quartz.dataSource.myDS.maxConnections: 25
org.quartz.dataSource.myDS.validationQuery: select 0

#集群下添加该设置有助于阻止某些数据库在高负载和长时间事物时锁的超时
org.quartz.jobStore.txIsolationLevelSerializable=true

说明:数据库配置myDS为加密配置重写jar包中的org.quartz.impl. StdSchedulerFactory类
2、创建调度器,并启动
package com.huateng.report.scheduler.timer;

import java.sql.Connection;
import java.sql.Statement;
import java.text.ParseException;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerKey;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

import resource.bean.report.ReportJobConfig;

import com.huateng.ebank.business.common.ROOTDAO;
import com.huateng.ebank.business.common.ROOTDAOUtils;
import com.huateng.ebank.business.innerinterface.ITimedScheduler;
import com.huateng.ebank.framework.exceptions.CommonException;

/*******************************************************************************

  • 定时器类
    ******************************************************************************/

public class CICSTimedScheduler implements ITimedScheduler {
private static Logger logger = Logger.getLogger(CICSTimedScheduler.class);
private static String JOB_GROUP_NAME = “CICS_PICS_JOB”;
private static String TRIGGER_GROUP_NAME = “CICS_PICS_JOB_TRIGGER”;
private static ServletContext ctx = null;
private static SchedulerFactory sf = new StdSchedulerFactory();

public void runNow(String jobid) {
	try {
		Scheduler sched = sf.getScheduler();
		JobKey JobKey = new JobKey(jobid, JOB_GROUP_NAME);
		sched.triggerJob(JobKey);
	} catch (SchedulerException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

}

// 初始化加载
public void run(ServletContext context) throws CommonException {
	ctx = context;
	Connection conn = null;
	 Statement stmt = null;
	try {
		ROOTDAO rootdao = ROOTDAOUtils.getROOTDAO();
		conn = SessionFactoryUtils.getDataSource(rootdao.getSessionFactory()).getConnection();
		stmt = conn.createStatement(); 
		stmt.addBatch("delete from QRTZ_CALENDARS"); 
		stmt.addBatch("delete from QRTZ_FIRED_TRIGGERS"); 
		stmt.addBatch("delete from QRTZ_PAUSED_TRIGGER_GRPS"); 
		stmt.addBatch("delete from QRTZ_SCHEDULER_STATE"); 
		stmt.addBatch("delete from QRTZ_LOCKS"); 
		stmt.addBatch("delete from QRTZ_SIMPLE_TRIGGERS"); 
		stmt.addBatch("delete from QRTZ_CRON_TRIGGERS"); 
		stmt.addBatch("delete from QRTZ_BLOB_TRIGGERS"); 
		stmt.addBatch("delete from QRTZ_TRIGGERS"); 
		stmt.addBatch("delete from QRTZ_JOB_DETAILS"); 
		stmt.addBatch("delete from QRTZ_SIMPROP_TRIGGERS"); 
		stmt.executeBatch();       //执行批处理 
		
		
		String hql = "from ReportJobConfig model where model.jobStauts='" + ITimedScheduler.TIMED_STATUS_1 + "'";
		List<ReportJobConfig> list = rootdao.queryByQL2List(hql);
		if (list.size() > 0) {
			for (ReportJobConfig jobConfig : list) {
					CICSTimedScheduler.addJob(jobConfig.getId(),
							(Job) Class.forName(jobConfig.getJobClassName()).newInstance(), jobConfig.getJobTime());
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		if (stmt != null) {
			try {
				stmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			Scheduler sched = sf.getScheduler();
			sched.start();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		
	}
	

}

/**
 * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
 *
 * @param jobName
 *            任务名
 * @param job
 *            任务
 * @param time
 *            时间设置,参考quartz说明文档
 * @throws SchedulerException
 * @throws ParseException
 */
public static void addJob(String jobId, Job job, String time) throws SchedulerException, ParseException {
	
	Scheduler sched = sf.getScheduler();
	sched.getContext().put("serContext", ctx);
	JobDetailImpl jobDetail = new JobDetailImpl(jobId, JOB_GROUP_NAME, job.getClass());// 任务名,任务组,任务执行类
	jobDetail.getJobDataMap().put("jobId", jobId);
	// 触发器
	CronTriggerImpl trigger = new CronTriggerImpl(jobId, TRIGGER_GROUP_NAME);// 触发器名,触发器组
	trigger.setCronExpression(time);// 触发器时间设定
	sched.scheduleJob(jobDetail, trigger);
	logger.info("添加任务: " + jobId);
		
}

/**
 * 移除一个任务
 *
 * @param jobName
 * @param jobGroupName
 * @param triggerName
 * @param triggerGroupName
 * @throws SchedulerException
 */
public static void removeJob(String jobId) throws SchedulerException {
	Scheduler sched = sf.getScheduler();
	TriggerKey TriggerKey = new TriggerKey(jobId, TRIGGER_GROUP_NAME);
	JobKey JobKey = new JobKey(jobId, JOB_GROUP_NAME);
	sched.pauseTrigger(TriggerKey);// 停止触发器
	sched.unscheduleJob(TriggerKey);// 移除触发器
	sched.deleteJob(JobKey);// 删除任务
	logger.info("移除任务:" + jobId);
}

}
3、创建quartz持久化的表(SqlServer版)

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]’) AND OBJECTPROPERTY(id, N’ISFOREIGNKEY’) = 1)
ALTER TABLE [QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISFOREIGNKEY’) = 1)
ALTER TABLE [QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISFOREIGNKEY’) = 1)
ALTER TABLE [QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISFOREIGNKEY’) = 1)
ALTER TABLE [QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_CALENDARS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_CALENDARS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_CRON_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_CRON_TRIGGERS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_BLOB_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_BLOB_TRIGGERS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_FIRED_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_FIRED_TRIGGERS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_PAUSED_TRIGGER_GRPS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_PAUSED_TRIGGER_GRPS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_SCHEDULER_STATE]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_SCHEDULER_STATE]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_LOCKS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_LOCKS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_JOB_DETAILS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_JOB_DETAILS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_SIMPLE_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_SIMPLE_TRIGGERS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_SIMPROP_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_SIMPROP_TRIGGERS]
GO

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N’[QRTZ_TRIGGERS]’) AND OBJECTPROPERTY(id, N’ISUSERTABLE’) = 1)
DROP TABLE [QRTZ_TRIGGERS]
GO

CREATE TABLE [QRTZ_CALENDARS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[CALENDAR_NAME] [VARCHAR] (200) NOT NULL ,
[CALENDAR] [IMAGE] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [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)
) ON [PRIMARY]
GO

CREATE TABLE [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] NOT NULL ,
[SCHED_TIME] [BIGINT] ,
[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
) ON [PRIMARY]
GO

CREATE TABLE [QRTZ_PAUSED_TRIGGER_GRPS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [QRTZ_SCHEDULER_STATE] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[INSTANCE_NAME] [VARCHAR] (200) NOT NULL ,
[LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
[CHECKIN_INTERVAL] [BIGINT] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [QRTZ_LOCKS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[LOCK_NAME] [VARCHAR] (40) NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [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] [IMAGE] NULL
) ON [PRIMARY]
GO

CREATE TABLE [QRTZ_SIMPLE_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[REPEAT_COUNT] [BIGINT] NOT NULL ,
[REPEAT_INTERVAL] [BIGINT] NOT NULL ,
[TIMES_TRIGGERED] [BIGINT] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [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,
) ON [PRIMARY]
GO

CREATE TABLE [QRTZ_BLOB_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[BLOB_DATA] [IMAGE] NULL
) ON [PRIMARY]
GO

CREATE TABLE [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] NULL ,
[PREV_FIRE_TIME] [BIGINT] NULL ,
[PRIORITY] [INTEGER] NULL ,
[TRIGGER_STATE] [VARCHAR] (16) NOT NULL ,
[TRIGGER_TYPE] [VARCHAR] (8) NOT NULL ,
[START_TIME] [BIGINT] NOT NULL ,
[END_TIME] [BIGINT] NULL ,
[CALENDAR_NAME] [VARCHAR] (200) NULL ,
[MISFIRE_INSTR] [SMALLINT] NULL ,
[JOB_DATA] [IMAGE] NULL
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_CALENDARS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[CALENDAR_NAME]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[ENTRY_ID]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[INSTANCE_NAME]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_LOCKS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[LOCK_NAME]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_JOB_DETAILS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
GO

ALTER TABLE [QRTZ_CRON_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
GO

ALTER TABLE [QRTZ_SIMPLE_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
GO

ALTER TABLE [QRTZ_SIMPROP_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
GO

ALTER TABLE [QRTZ_TRIGGERS] ADD
CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
(
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
) REFERENCES [QRTZ_JOB_DETAILS] (
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
)
GO
表与字段说明:
quartz框架中T_TASK_TRIGGERS表 TRIGGER_STATE 字段显示任务的属性大概状态有这几种:
WAITING:等待
PAUSED:暂停
ACQUIRED:正常执行
BLOCKED:阻塞
ERROR:错误
主要使用以上这几种状态控制调度各节点定时任务
QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息
QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括Cron表达式和时区信息
QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger组的信息
QRTZ_SCHEDULER_STATE 存储少量的有关 Scheduler 的状态信息,和别的Scheduler实例(假如是用于一个集群中)
QRTZ_LOCKS 存储程序的悲观锁的信息(假如使用了悲观锁)
QRTZ_JOB_DETAILS 存储每一个已配置的 Job 的详细信息
QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener的信息
QRTZ_SIMPLE_TRIGGERS存储简单的Trigger,包括重复次数,间隔,以及已触的次数
QRTZ_BLOG_TRIGGERS Trigger 作为 Blob 类型存储(用于 Quartz 用户用JDBC创建他们自己定制的 Trigger 类型,JobStore并不知道如何存储实例的时候)
QRTZ_TRIGGER_LISTENERS 存储已配置的 TriggerListener的信息
QRTZ_TRIGGERS 存储已配置的 Trigger 的信息

表qrtz_job_details:保存job详细信息,该表需要用户根据实际情况初始化
job_name:集群中job的名字,该名字用户自己可以随意定制,无强行要求
job_group:集群中job的所属组的名字,该名字用户自己随意定制,无强行要求
job_class_name:集群中个notejob实现类的完全包名,quartz就是根据这个路径到classpath找到该job类
is_durable:是否持久化,把该属性设置为1,quartz会把job持久化到数据库中
job_data:一个blob字段,存放持久化job对象

表qrtz_triggers: 保存trigger信息
trigger_name:trigger的名字,该名字用户自己可以随意定制,无强行要求
trigger_group:trigger所属组的名字,该名字用户自己随意定制,无强行要求
job_name:qrtz_job_details表job_name的外键
job_group:qrtz_job_details表job_group的外键
trigger_state:当前trigger状态,设置为ACQUIRED,如果设置为WAITING,则job不会触发
trigger_cron:触发器类型,使用cron表达式

表qrtz_cron_triggers:存储cron表达式表
trigger_name:qrtz_triggers表trigger_name的外键
trigger_group:qrtz_triggers表trigger_group的外键
cron_expression:cron表达式

表qrtz_scheduler_state:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态
instance_name:之前配置文件中org.quartz.scheduler.instanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字
last_checkin_time:上次检查时间
checkin_interval:检查间隔时间

Job 实例
你可以创建一个 Job 类,然后通过创建多个 JobDetail 实例与 Job 关联,并保存到调度器中(每个任务都有自己的属性和 JobDataMap),这个 JobDetail 称为 Job 实例。
例如,你可以创建一个实现了 Job 接口的类,命名为“SalesReportJob”。这个类可以接收一个参数(通过 JobDataMap)用于定义销售报表基于哪个销售人员。它们可以创建多个 Job 实例(使用 JobDetail),例如 “SalesReportForJoe” 和 “SalesReportForMike”,这里使用了由 JobDataMap 传入 “joe” 和 “mike” 作为参数。
当 Trigger 被触发,关联的 JobDetail 将会被加载,并且 Job 类会通过 JobFactory 配置到 Scheduler。默认的 JobFactory 将会简单地调用 Job Class 的 newInstance() 方法,并尝试调用 set 方法将 JobDataMap 中同名的属性设置到 Job 中。
Job 状态和并发
有一组可添加到 Job 的 Annotation,可以影响 Quartz 的行为。
@DisallowConcurrentExecution 添加到 Job 类后,Quartz 将不会同时执行多个 Job 实例(什么是 Job 实例可参看上一节)。
注意措辞。我们用上一节的例子来讲解,如果 “SalesReportJob” 上添加了这个 Annotation,那么同时只能执行一个“SalesReportForJoe”,但是却可以同时执行“SalesReportForMike”。因此,可以说这个约束是基于 JobDetail 的而不是基于 Job 的。
@PersistJobDataAfterExecution 添加到 Job 类后,表示 Quartz 将会在成功执行 execute() 方法后(没有抛出异常)更新 JobDetail 的 JobDataMap,下一次执行相同的任务(JobDetail)将会得到更新后的值,而不是原始的值。就像 @DisallowConcurrentExecution 一样,这个注释基于 JobDetail 而不是 Job 类的实例。
如果你使用了 @PersistJobDataAfterExecution 注释,那么强烈建议你使用 @DisallowConcurrentExecution 注释,这是为了避免出现并发问题,当多个 Job 实例同时执行的时候,到底使用了哪个数据将变得很混乱。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值