首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Quartz(3)原理及源码分析

2012-11-18 
Quartz(三)原理及源码分析quartz配置文件中可以通过以下两种配置读取方式org.quartz.jobStore.class org

Quartz(三)原理及源码分析
quartz配置文件中可以通过以下两种配置读取方式
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore(从内存中读取定时任务)
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX(从数据库中读取定时任务)

以JobStoreTX为例,它最核心的组成部分是Scheduler、Trigger、JobDetail,然后给Scheduler配置个线程QuartzSchedulerThread,此线程在服务器启动时初始化Scheduler时启动,等待Scheduler start,然后从JobStore里拿到最近要触发的Trigger。
Scheduler:接口定义了对定时任务主要操作方法。
Trigger:定时器定义了任务执行时间。
JobDetail:定时任务一个JobDetail可以配置多个Trigger,主要定义了定时执行的类,方法,参数等信息。


任务定时执行:在服务器启动以后,每隔几秒至几十秒就会轮询StdJDBCDelegate类中selectTriggerToAcquire方法,执行sql查询qrtz_triggers表中NEXT_FIRE_TIME(下次触发时间)字段符合当前时间段并且TRIGGER_STATE状态为WAITING(等待中),符合此条件的Trigger查询出来,关联jobDetail来得到配置参数,调用配置好的业务方法。

    if(updateJobData) {ps = conn.prepareStatement(rtp(UPDATE_TRIGGER));} else {ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_SKIP_DATA));}ps.setString(1, trigger.getJobName());ps.setString(2, trigger.getJobGroup());setBoolean(ps, 3, trigger.isVolatile());ps.setString(4, trigger.getDescription());long nextFireTime = -1;if (trigger.getNextFireTime() != null) {nextFireTime = trigger.getNextFireTime().getTime();}ps.setBigDecimal(5, new BigDecimal(String.valueOf(nextFireTime)));long prevFireTime = -1;if (trigger.getPreviousFireTime() != null) {prevFireTime = trigger.getPreviousFireTime().getTime();}ps.setBigDecimal(6, new BigDecimal(String.valueOf(prevFireTime)));ps.setString(7, state);if (trigger instanceof SimpleTrigger && ((SimpleTrigger)trigger).hasAdditionalProperties() == false ) {//                updateSimpleTrigger(conn, (SimpleTrigger)trigger);ps.setString(8, TTYPE_SIMPLE);} else if (trigger instanceof CronTrigger && ((CronTrigger)trigger).hasAdditionalProperties() == false ) {//                updateCronTrigger(conn, (CronTrigger)trigger);ps.setString(8, TTYPE_CRON);} else {//                updateBlobTrigger(conn, trigger);ps.setString(8, TTYPE_BLOB);}ps.setBigDecimal(9, new BigDecimal(String.valueOf(trigger.getStartTime().getTime())));//代码略......

注意:在调试和测试quartz时,在局域网下如果没有做服务器集群,多个人启动了多台服务器,连接到同一台数据库服务器时会出现问题,因为quartz是多线程的,通过数据表记录来获得执行的任务,当多台服务器异步更新和读取的时候就会造成数据读取不同步问题,而出现bug。解决办法就是,测试时自己单独使用一个数据库,或是修改配置文件让其他人通过RAMJobStore读取,这样就不会造成多台机器同时读取一个库的问题发生了。

热点排行