作业调度框架 Quartz 学习笔记(六) -- job生病了(抛出异常)时的处理
job 处理过程中
如果 发生了异常处理
BadJob1.java
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class BadJob2 implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
// 任务执行的时间
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String jobName = context.getJobDetail().getKey().getName();
System.out.println("---" + jobName + " 在[ " + dateFormat.format(new Date())+ " ] 执行!! ") ;
System.err.println("--- 在 BadJob 2 中发生 错误, 将停止运行!! ");
JobExecutionException e2 = new JobExecutionException(new Exception());
// 设置 将自动 去除 这个任务的触发器,所以这个任务不会再执行
//e2.setUnscheduleAllTriggers(true);
// 抛出异常
throw e2;
}
}
BadJob2.java
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class BadJob2 implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
// 任务执行的时间
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String jobName = context.getJobDetail().getKey().getName();
System.out.println("---" + jobName + " 在[ " + dateFormat.format(new Date())+ " ] 执行!! ") ;
System.err.println("--- 在 BadJob 2 中发生 错误, 将停止运行!! ");
JobExecutionException e2 = new JobExecutionException(new Exception());
// 设置 将自动 去除 这个任务的触发器,所以这个任务不会再执行
e2.setUnscheduleAllTriggers(true);
// 抛出异常
throw e2;
}
}
一个调度类: JobExceptionExample.java
import static org.quartz.DateBuilder.nextGivenSecondDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
/** 演示 Quartz 如何 处理 从job中 抛出的 JobExecutionExceptions */
public class JobExceptionExample {
public static void main(String[] args) throws Exception {
JobExceptionExample example = new JobExceptionExample();
example.run();
}
public void run() throws Exception {
// 任务执行的时间 格式化
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
System.out.println("--------------- 初始化 -------------------");
// 下一个15秒
Date startTime = nextGivenSecondDate(null, 15);
// badJob1 每10s执行一次 , 抛出异常,并立即重新执行
JobDetail job = newJob(BadJob1.class).withIdentity("badJob1", "group1").usingJobData("denominator", "0").build();
SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(startTime)
.withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();
Date ft = sched.scheduleJob(job, trigger);
System.out.println(job.getKey().getName() + " 将在: " + dateFormat.format(ft) + " 时运行.并且重复: "
+ trigger.getRepeatCount() + " 次, 每次间隔 " + trigger.getRepeatInterval() / 1000 + " 秒");
// badJob2 每5秒执行一次 , 并且 会抛出异常,然后 不再执行
job = newJob(BadJob2.class).withIdentity("badJob2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").startAt(startTime)
.withSchedule(simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();
ft = sched.scheduleJob(job, trigger); //
System.out.println(job.getKey().getName() + " 将在: " + dateFormat.format(ft) + " 时运行.并且重复: "
+ trigger.getRepeatCount() + " 次, 每次间隔 " + trigger.getRepeatInterval() / 1000 + " 秒");
sched.start();
System.out.println("------- 开始调度 (调用.start()方法) ----------------");
try {
// 睡眠 30s
Thread.sleep(60L * 1000L);
} catch (Exception e) {
}
sched.shutdown(false);
// 显示一下 已经执行的任务信息
SchedulerMetaData metaData = sched.getMetaData();
System.out.println("~~~~~~~~~~ 执行了 " + metaData.getNumberOfJobsExecuted() + " 个 jobs.");
}
}
说明:
2 类BadJob1 的代码 34-44 行 从Map 中取出 denominator 如果 是0 抛出异常,然后将denominator设置成1,也就是说只有第一次会有异常抛出,以后都 正常
代码 41 行是关键: e2.setRefireImmediately(true); 它设置了 job 类抛出异常后的处理方式 ,此处意为 发生异常后 立即重新执行
但在 第26行处: e2.setUnscheduleAllTriggers(true);
设置了 去掉它的 触发器, 也就意味着 BadJob2 如果 发生异常,就没有机会再执行了 (悲催的孩子) 0.0
@PersistJobDataAfterExecution
@DisallowConcurrentExecution