作业调度框架 Quartz 学习笔记(六) -- job生病了(抛出异常)时的处理

时间:2021-05-23 08:08:29

我们一直没有太深入的去完成 一个job 类,因为这是跟你的实际应用紧密相关联的,但是在你的job 处理过程中

如果 发生了异常,那么会怎么样处理呢 ? 客官您往下看…………

------------------------------------我是分割线------------------------------------------------

如果客官看过前面的几篇 烂的掉渣的 文章后,会知道下面会先贴代码,一个job类,一个调度类。

但这次有点不同的是这次 没有烂的掉渣,而是烂的更掉渣,-.- 

两个job类:BadJob1.java  和 BadJob2.java

一个调度类:  JobExceptionExample.java                

BadJob1.java 

  1. import java.text.SimpleDateFormat;  
  2. import java.util.Date;  
  3.   
  4. import org.quartz.DisallowConcurrentExecution;  
  5. import org.quartz.Job;  
  6. import org.quartz.JobExecutionContext;  
  7. import org.quartz.JobExecutionException;  
  8. import org.quartz.PersistJobDataAfterExecution;  
  9.   
  10. @PersistJobDataAfterExecution  
  11. @DisallowConcurrentExecution  
  12. public class BadJob2 implements Job {  
  13.   
  14.     @Override  
  15.     public void execute(JobExecutionContext context)  
  16.             throws JobExecutionException {  
  17.         // 任务执行的时间  
  18.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  19.         String jobName = context.getJobDetail().getKey().getName();  
  20.         System.out.println("---" + jobName + " 在[ " + dateFormat.format(new Date())+ " ] 执行!!  ") ;  
  21.         System.err.println("--- 在 BadJob  2   中发生 错误, 将停止运行!! ");  
  22.         JobExecutionException e2 = new JobExecutionException(new Exception());  
  23.         // 设置 将自动 去除 这个任务的触发器,所以这个任务不会再执行  
  24.         //e2.setUnscheduleAllTriggers(true);  
  25.           
  26.         // 抛出异常  
  27.         throw e2;  
  28.     }  
  29. }  


BadJob2.java

  1. import java.text.SimpleDateFormat;  
  2. import java.util.Date;  
  3.   
  4. import org.quartz.DisallowConcurrentExecution;  
  5. import org.quartz.Job;  
  6. import org.quartz.JobExecutionContext;  
  7. import org.quartz.JobExecutionException;  
  8. import org.quartz.PersistJobDataAfterExecution;  
  9.   
  10. @PersistJobDataAfterExecution  
  11. @DisallowConcurrentExecution  
  12. public class BadJob2 implements Job {  
  13.   
  14.     @Override  
  15.     public void execute(JobExecutionContext context)  
  16.             throws JobExecutionException {  
  17.         // 任务执行的时间  
  18.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  19.         String jobName = context.getJobDetail().getKey().getName();  
  20.         System.out.println("---" + jobName + " 在[ " + dateFormat.format(new Date())+ " ] 执行!!  ") ;  
  21.         System.err.println("--- 在 BadJob  2   中发生 错误, 将停止运行!! ");  
  22.         JobExecutionException e2 = new JobExecutionException(new Exception());  
  23.         // 设置 将自动 去除 这个任务的触发器,所以这个任务不会再执行  
  24.         e2.setUnscheduleAllTriggers(true);  
  25.         // 抛出异常  
  26.         throw e2;  
  27.     }  
  28. }  


JobExceptionExample.java

 

  1. import static org.quartz.DateBuilder.nextGivenSecondDate;  
  2. import static org.quartz.JobBuilder.newJob;  
  3. import static org.quartz.SimpleScheduleBuilder.simpleSchedule;  
  4. import static org.quartz.TriggerBuilder.newTrigger;  
  5.   
  6. import java.text.SimpleDateFormat;  
  7. import java.util.Date;  
  8.   
  9. import org.quartz.JobDetail;  
  10. import org.quartz.Scheduler;  
  11. import org.quartz.SchedulerFactory;  
  12. import org.quartz.SchedulerMetaData;  
  13. import org.quartz.SimpleTrigger;  
  14. import org.quartz.impl.StdSchedulerFactory;  
  15.   
  16. /** 演示 Quartz 如何 处理 从job中 抛出的 JobExecutionExceptions */  
  17. public class JobExceptionExample {  
  18.   
  19.     public static void main(String[] args) throws Exception {  
  20.         JobExceptionExample example = new JobExceptionExample();  
  21.         example.run();  
  22.     }  
  23.   
  24.     public void run() throws Exception {  
  25.         // 任务执行的时间 格式化  
  26.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  27.   
  28.         SchedulerFactory sf = new StdSchedulerFactory();  
  29.         Scheduler sched = sf.getScheduler();  
  30.         System.out.println("--------------- 初始化 -------------------");  
  31.       
  32.         // 下一个15秒  
  33.         Date startTime = nextGivenSecondDate(null15);  
  34.   
  35.         // badJob1 每10s执行一次 , 抛出异常,并立即重新执行   
  36.         JobDetail job = newJob(BadJob1.class).withIdentity("badJob1""group1").usingJobData("denominator""0").build();     
  37.   
  38.         SimpleTrigger trigger = newTrigger().withIdentity("trigger1""group1").startAt(startTime)  
  39.             .withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();  
  40.   
  41.         Date ft = sched.scheduleJob(job, trigger);  
  42.         System.out.println(job.getKey().getName() + " 将在: " + dateFormat.format(ft) + "  时运行.并且重复: "  
  43.             + trigger.getRepeatCount() + " 次, 每次间隔 " + trigger.getRepeatInterval() / 1000 + " 秒");  
  44.   
  45.         // badJob2 每5秒执行一次 , 并且 会抛出异常,然后 不再执行  
  46.         job = newJob(BadJob2.class).withIdentity("badJob2""group1").build();  
  47.   
  48.         trigger = newTrigger().withIdentity("trigger2""group1").startAt(startTime)  
  49.             .withSchedule(simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();  
  50.   
  51.         ft = sched.scheduleJob(job, trigger); //  
  52.         System.out.println(job.getKey().getName() + " 将在: " + dateFormat.format(ft) + "  时运行.并且重复: "  
  53.             + trigger.getRepeatCount() + " 次, 每次间隔 " + trigger.getRepeatInterval() / 1000 + " 秒");  
  54.   
  55.         sched.start();  
  56.         System.out.println("------- 开始调度 (调用.start()方法) ----------------");  
  57.   
  58.         try {  
  59.             // 睡眠 30s  
  60.             Thread.sleep(60L * 1000L);  
  61.         } catch (Exception e) {  
  62.         }  
  63.   
  64.         sched.shutdown(false);  
  65.   
  66.         // 显示一下 已经执行的任务信息  
  67.         SchedulerMetaData metaData = sched.getMetaData();  
  68.         System.out.println("~~~~~~~~~~  执行了 " + metaData.getNumberOfJobsExecuted() + " 个 jobs.");  
  69.     }  
  70. }  


说明:

1 类JobExceptionExample.java 没什么可说的了,完全 按套路走的

2 类BadJob1 的代码 34-44 行 从Map 中取出 denominator 如果 是0 抛出异常,然后将denominator设置成1,也就是说只有第一次会有异常抛出,以后都 正常

      代码 41   行是关键:  e2.setRefireImmediately(true); 它设置了 job 类抛出异常后的处理方式 ,此处意为 发生异常后 立即重新执行

3 类BadJob2 的代码 和 BadJob1 不同,它没有判断,执行一次 就抛出一次异常,

      但在 第26行处: e2.setUnscheduleAllTriggers(true);

        设置了 去掉它的 触发器, 也就意味着 BadJob2 如果 发生异常,就没有机会再执行了 (悲催的孩子) 0.0

 

提醒: 别忘了 BadJob类上的

@PersistJobDataAfterExecution
@DisallowConcurrentExecution

 这两句注释

 

一个小问题: 如果 发生异常 而没有设置 异常时的处理策略 那会是什么样,自己试试把BadJob2 中的 代码 注释掉 看看结果吧