Spring+quartz 动态任务调度



Spring+quartz 动态任务调度

需求是这样的:系统中会有很多的执行时间,三个或者四个这样,不确定,以后可能是五个!当用户在页面添加执行时间时,我们后台也要对应执行用户添加的时间。

数据库设计:

 

  1. DROP TABLE IF EXISTS `test_time_task`;
  2. CREATE TABLE `test_time_task` (
  3.   `status` int(11) DEFAULT NULL COMMENT ’状态:0为正常,1为禁用’,
  4.   `job` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT ’执行时间’,
  5.   `id` int(11) DEFAULT NULL COMMENT ’编号’
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf-8;
  7. – —————————-
  8. – Records of test_time_task
  9. – —————————-
  10. INSERT INTO `test_time_task` VALUES (’0′, ’0 30 9 * * ?’, ’1′);
  11. INSERT INTO `test_time_task` VALUES (’0′, ’0 30 11 * * ?’, ’2′);
  12. INSERT INTO `test_time_task` VALUES (’0′, ’0 30 16 * * ?’, ’3′);

查询语句,其中的#{hourMinute}为查询条件,格式——’12:11′:

 

 

  1. select  case when (select job
  2.          from (select job,RTRIM(substr(substr(job,6,7),1,2)) as hour,  LTRIM(substr(job,2,3)) as minute from test_time_task where  status = 0 ) as mytable
  3.         where
  4.          str_to_date( CONCAT(hour,’:',minute),’%k:%i’)>  str_to_date(  #{hourMinute} ,’%k:%i’)  order by str_to_date(hour,’%k’) LIMIT 1) is null then
  5.         (select job
  6.          from (select job,RTRIM(substr(substr(job,6,7),1,2)) as hour,  LTRIM(substr(job,2,3)) as minute from test_time_task where  status = 0 ) as mytable
  7.          order by  str_to_date( CONCAT(hour,’:',minute),’%k:%i’) LIMIT 1) else
  8.          (select job
  9.          from (select job,RTRIM(substr(substr(job,6,7),1,2)) as hour,  LTRIM(substr(job,2,3)) as minute from test_time_task where  status = 0 ) as mytable
  10.         where
  11.          str_to_date( CONCAT(hour,’:',minute),’%k:%i’)>  str_to_date(  #{hourMinute} ,’%k:%i’)  order by str_to_date(hour,’%k’) LIMIT 1) end

Spring配置文件:

 

 

  1. <?xml version=”1.0″ encoding=”UTF-8″?>
  2. <!DOCTYPE beans PUBLIC ”-//SPRING//DTD BEAN//EN” ”http://www.springframework.org/dtd/spring-beans.dtd”>
  3. <beans>
  4.     <!– 被执行类 –>
  5.     <bean id=”testQuarzt” class=”cmcc.gz.pmp.timetest.service.ScheduleInfoService”>
  6.         <property name=”scheduler” ref=”schedulerFactory” />
  7.     </bean>
  8.     <!– 将testQuarzt注入到job中 –>
  9.     <bean id=”testQuartzJob”
  10.         class=”org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean”>
  11.         <property name=”targetObject” ref=”testQuarzt” />
  12.         <property name=”targetMethod” value=”loadJob” />
  13.         <property name=”concurrent” value=”false” />
  14.     </bean>
  15.     <!– 将job注入到定时触发器 –>
  16.     <bean id=”testTrigger” class=”org.springframework.scheduling.quartz.CronTriggerBean”>
  17.         <property name=”jobDetail” ref=”testQuartzJob” />
  18.         <property name=”cronExpression”>
  19.             <value>0/1 * * * * ?</value>
  20.         </property>
  21.     </bean>
  22.     <!– 将触发器注入任务工程 –>
  23.     <bean id=”schedulerFactory”
  24.         class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
  25.         <property name=”triggers”>
  26.             <list>
  27.                 <ref bean=”testTrigger” />
  28.             </list>
  29.         </property>
  30.     </bean>
  31. </beans>

java程序代码:

 


 

  1. import java.text.ParseException;
  2. import java.util.Date;
  3. import org.quartz.Scheduler;
  4. import org.quartz.SchedulerException;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.scheduling.quartz.CronTriggerBean;
  7. import cmcc.gz.pmp.timetest.db.mapper.JobMapper;
  8. import cmcc.gz.pmp.util.CommonDate;
  9. /**
  10.  *
  11.  * 类描述:时间任务调度测试方法
  12.  * @author 胡汉三
  13.  * 创建时间:2014-5-26 下午6:11:55
  14.  *
  15.  */
  16. public class ScheduleInfoService {
  17.     @Autowired
  18.     private JobMapper mapper;
  19.     private Scheduler scheduler;
  20.     // 设值注入,通过setter方法传入被调用者的实例scheduler
  21.     public void setScheduler(Scheduler scheduler) {
  22.         this.scheduler = scheduler;
  23.     }
  24.     public void loadJob() throws SchedulerException, ParseException{
  25.         Object j = mapper.findJob(CommonDate.getTimeNow(new Date()));
  26.         // 运行时可通过动态注入的scheduler得到trigger,注意采用这种注入方式在有的项目中会有问题,如果遇到注入问题,可以采        取在运行方法时候,获得bean来避免错误发生。
  27.         CronTriggerBean trigger =  (CronTriggerBean)scheduler.getTrigger(“testTrigger”,Scheduler.DEFAULT_GROUP);
  28.         String originConExpression = trigger.getCronExpression();
  29.         // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob 也不需要去执行任务
  30.         if(!originConExpression.equalsIgnoreCase(j.toString())){
  31.             //如果不是系统启动时的任务,就去执行它
  32.             if(!originConExpression.equalsIgnoreCase(“0/1 * * * * ?”)){
  33.                 /** 执行任务 **/
  34.                 test();
  35.             }
  36.             System.out.println(j.toString());
  37.             trigger.setCronExpression(j.toString());
  38.             scheduler.rescheduleJob(“testTrigger”, Scheduler.DEFAULT_GROUP, trigger);
  39.         }
  40.     }
  41.     /**
  42.      * 执行任务
  43.      */
  44.     public void test(){
  45.         System.out.println(“XML任务进行中…”);
  46.     }
  47. }

测试时,当我把我的系统时间改为九点29的时候等到30就会执行,结果跟过程都正常,
更改到十一点半正常,更改到十六点半正常,当我更改到第二天九29的时候,执行就出错了:

 

Invocation of method 'resetJob' on target class [class cmcc.gz.pmp.timetest.service.ScheduleInfoService$$EnhancerByCGLIB$$11b080f3] failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

解决办法:

Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。
它默认是8小时,我们手动改大一些,在测试就通过了!

 

查看:show global variables like 'wait_timeout';
修改:set global wait_timeout=86999;

 

 

帖子地址:点击打开链接

http://blog.csdn.net/hzw2312/article/details/27358795