定时任务-暂停、开始、更新、删除


对于后端开发来说,定时任务的使用频率非常高,当然也少不了定时任务的管理了。最常见的应用就是单节点定时任务持久化的实现,需求稍微多一点就需要对定时任务管理,暂停、删除、恢复等;本文在SpringBoot&quartz的项目上讲解;

单节点定时任务持久化的Demo地址:SpringBoot整合quartz完成定时任务单节点持久化,Demo未添加定时任务的管理,可以再其基础上修改即可,需要手动添加定时任务实体。

放上定时任务实体字段:

@ApiModelProperty(value = "主键,添加是不能有值,修改时必须有值")
@Id
@GeneratedValue(generator = "ID")
@GenericGenerator(name = "ID", strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private String id;

@ApiModelProperty(value = "定时定时任务名称,不能超过30个字符", required = true)
@NotBlank(message = "定时任务名称不能为空")
@Length(max = 30, message = "定时任务名称不能超过30个字符")
@Basic
@Column(name = "JOB_NAME")
private String jobName;

@ApiModelProperty(value = "任务组,项目传1", required = true)
@NotNull(message = "任务组不能为空")
@Basic
@Column(name = "JOB_GROUP")
private String jobGroup;

@ApiModelProperty(value = "任务ID", required = true)
@NotNull(message = "任务ID不能为空")
@Basic
@Column(name = "TASK_ID")
private Long taskId;

@ApiModelProperty(value = "时间表达式,只能含有英文、数字、空格、?、*、,、/、#", required = true)
@NotBlank(message = "时间表达式不能为空")
@Length(max = 60, message = "时间表达式不能超过60个字符")
@Basic
@Column(name = "CRON_EXPRESSION")
private String cronExpression;

@ApiModelProperty(value = "备注,不能超过300个字符")
@Length(max = 300, message = "备注不能超过300个字符")
@Basic
@Column(name = "REMARK")
private String remark;

@ApiModelProperty(hidden = true)
@Column(name = "D_OPDT_", nullable = true, precision = 0)
private Long dOpdt;

@ApiModelProperty(hidden = true)
@Column(name = "D_FLAG_", nullable = true, length = 1)
private String dFlag;

@ApiModelProperty(hidden = true)
@Column(name = "D_OPER_", nullable = true, length = 36)
private String dOper;

代码之间的调用、注入省略掉了,本文只助于理解。

添加定时任务

实体中判断是否为时间表达式可使用CronExpression.isValidExpression判断false为错误的时间表达式,反之正确。

CronJobBean cronJobBean = new CronJobBean();
...
JobDataMap dataMap = new JobDataMap();
dataMap.put("cronJob", cronJobBean);
quartzManager.addJob(cronJobBean, dataMap);
...
// controlelr层中接收两个参数:CronJobBean cronJob, JobDataMap dataMap
// 一般单个任务一个类,类中写任务的逻辑,这里的任务类为CommonJob
// 任务类 继承 QuartzJobBean 类, 实现 executeInternal 方法, 参数:jobExecutionContext 任务执行上下文
// 构建一个任务的详情
JobDetail jobDetail = JobBuilder.newJob(CommonJob.class)
   .withIdentity(cronJob.getJobName(),cronJob.getJobGroup()).setJobData(dataMap).build();
// 构建时间表达式
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
    .cronSchedule(cronJob.getCronExpression());
// 创建一个触发器
Trigger trigger = TriggerBuilder.newTrigger()
    .withIdentity(cronJob.getJobName(), cronJob.getJobGroup())
    .withSchedule(scheduleBuilder).build();
try {
    // 将触发器加入到scheduler中
    scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
    e.printStackTrace();
}

开始定时任务

开始定时任务调用方法即可。

/**
* 开始一个定时任务
*
* @param jobName
* @param jobGroupName
* @return void
* @throws
*/
public void startJob(String jobName, String jobGroupName) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
    scheduler.triggerJob(jobKey);
}

暂停定时任务

暂定定时任务调用scheduler的方法即可。

/**
* 根据任务名称,任务组名,暂停一个定时任务
*
* @param jobName      任务名称
* @param jobGroupName 任务组名
* @return void
* @throws
*/
public void pauseJob(String jobName, String jobGroupName) throws SchedulerException {
    JobKey jk = new JobKey(jobName, jobGroupName);
    scheduler.pauseJob(jk);
}

暂定一组定时任务:参数为GroupMatcher<JobKey> groupmatcher,也是调用scheduler.pauseJobs(groupmatcher)方法即可。

暂停触发器与暂停定时任务同理,只是修改key为TriggerKey,调用的方法为pauseTrigger

恢复定时任务

恢复定时任务直接调用方法。

/**
* 根据任务名称,任务组名,恢复一个定时任务
*
* @param jobName      任务名称
* @param jobGroupName 任务组名
* @return void
* @throws
*/
public void resumeJob(String jobName, String jobGroupName) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
    scheduler.resumeJob(jobKey);
}

恢复一组定时任务:参数为GroupMatcher<JobKey> matcher,调用scheduler.resumeJobs(matcher)即可。

恢复一组触发器与恢复定时任务同理,只是修改key为TriggerKey,调用的方法为resumeTrigger

更新定时任务

根据传入的实体类重构job。

/**
 * 更新一个job
 *
 * @param cronJob
 * @return void
 * @throws
 */
public void updateJob(CronJobBean cronJob) {
    try {
        TriggerKey triggerKey = TriggerKey
            .triggerKey(cronJob.getJobName(),cronJob.getJobGroup());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        // 构建时间表达式
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
            .cronSchedule(cronJob.getCronExpression());
        // 按新的cronExpression表达式重新构建trigger
        trigger = trigger.getTriggerBuilder()
            .withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
        // 按新的trigger重新设置job执行
        scheduler.rescheduleJob(triggerKey, trigger);
    } catch (SchedulerException e) {
        e.printStackTrace();
    }
}

删除定时任务

删除定时任务以及相关的触发器

删除定时任务涉及到相关触发器,全部删除需要手动删除。参数灵活使用,也可加上触发器名称,触发器组名称。

// 参数为String jobName, String group
TriggerKey tk = TriggerKey.triggerKey(jobName, group);
JobKey jk = new JobKey(jobName, group);
scheduler.unscheduleJob(tk);
scheduler.deleteJob(jk);

删除触发器

// 参数为String triggerName, String triggergroup
TriggerKey tk = new TriggerKey(triggerName, triggergroup);
scheduler.unscheduleJob(tk);

Quartz常用注解

@PersistJobDataAfterExecution :告诉Quartz在任务执行成功完毕之后(没有抛出异常),修改JobDetail的JobDataMap备份,以供下一个任务使用。

Quartz定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行, 如果定时任执行太长,会长时间占用资源,导致其它任务堵塞。

@DisallowConcurrentExecution:禁止并发执行多个相同定义的JobDetail,可以并发执行同一个JobDetail。

建议两个注解同时使用!

文章最后附上Quartz 中文文档:Quartz中文文档


文章作者: Cody_
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Cody_ !
评论
 上一篇
Vue知识点及基础 Vue知识点及基础
记录一次Vue知识点的讲解笔记以及一些前端小知识 基础ES5 数组map:遍历,得到新数组 [1, 2, 3].map(i => i*2) // [2, 4, 6] find:查找一个元素,返回元素 [1, 2, 3].find(i =>
2019-05-29
下一篇 
(转)NamedParameterJdbcTemplate常用方法总结 (转)NamedParameterJdbcTemplate常用方法总结
NamedParameterJdbcTemplate类拓展了JdbcTemplate类,对JdbcTemplate类进行了封装从而支持命名参数特性。 NamedParameterJdbcTemplate主要提供以下三类方法:execute
2019-05-10
  目录