如何在quartz的job任务中 *** 作数据库

如何在quartz的job任务中 *** 作数据库,第1张

数据库中建表。建表模版在Quartz包下docs/dbTables下,选择相应的数据库和版本即可。ORACLE的11个Table列表如下:

QRTZ_JOB_LISTENERS:存储有关已配置的 JobListener 的信息

JOB_NAME

JOB_GROUP

JOB_LISTENER

QRTZ_TRIGGER_LISTENERS:存储已配置的 TriggerListener 的信息

QRTZ_FIRED_TRIGGERS:存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息

QRTZ_PAUSED_TRIGGER_GRPS:存储已暂停的 Trigger 组的信息

QRTZ_SCHEDULER_STATE:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态

INSTANCE_NAME 之前配置文件中orgquartzschedulerinstanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字

LAST_CHECKIN_TIME:上次检查时间

CHECKIN_INTERVAL :检查间隔时间

QRTZ_LOCKS:存储程序的悲观锁的信息(假如使用了悲观锁)

QRTZ_SIMPLE_TRIGGERS:存储简单的Trigger,包括重复次数,间隔,以及已触的次数

TRIGGER_NAME :qrtz_triggers表trigger_name的外键

TRIGGER_GROUP:qrtz_triggers表trigger_group的外键

REPEAT_COUNT :重复次数

REPEAT_INTERVAL:时间间隔

TIMES_TRIGGERED:触发次数

QRTZ_CRON_TRIGGERS:存储cron表达式表

TRIGGER_NAME :qrtz_triggers表trigger_name的外键

TRIGGER_GROUP:qrtz_triggers表trigger_group的外键

CRON_EXPRESSION:cron表达式

TIME_ZONE_ID :时区

QRTZ_TRIGGERS:保存trigger信息

crond是Linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,在CentOS Linux release 721511中默认是开机启动的,大家可以使用命令:systemctl status crond进行查看。 crond进程定期(每分钟)检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。用户在cron表

(也被称为crontab文件)指定了定时任务,crontab也就是我们常见的定时任务设置命令。Linux下的任务调度分为两类,系统任务调度和用户任务调度。

系统任务调度 :系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。/etc/crontab文件就是系统任务调度的配置文件。

用户任务调度 :用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab文件都被保存在/var/spool/cron目录中。其文件名与用户名一致,使用者权限文件如下:

通过以上帮助信息,我们可以知道crond是执行任务计划的一个守护进程。在使用crontab之前我们可以根据帮助信息来设置相关选项,一般情况下我们都使用默认值。

1建立演示账号crontab。

2星号()使用举例。

以上例子中完整演示了crontab从建立到执行的过程。“5 0 echo "GeekDevOps"”表示在每天00:05执行命令:echo "GeekDevOps"。后面的星号表示只要前面条件满足都执行。例子中的-u选项指定了用户:crontab,-l选项列举了相关用户的用户任务调度,不指定用户则默认为root。执行结果默认写入到用户mail目录下的相关文件中。

3逗号(,)的使用举例。

现在我们已经把用户切换到crontab下,因此无需额外指定-u选项相关内容。“3 2,6,8 ”表示每天的02:03:00、06:03:00、08:03:00分别执行一次命令:ls /usr/local。

4减号(-)的使用举例。

例子中的“0 2-6 6 df -h /”表示用户crontab在每周六的02:00、03:00、04:00、05:00、06:00执行命令:df -h / 。

5斜杠(/)的使用举例。

例子中表示每隔2分钟执行一次命令:echo "GeekDevOps">>/root/GeekDevOpstxt。

6crontab的使用非常简单,很容易理解,只要在取值范围内设置执行的值基本是没有问题的。现在我们要删除已经设置的这些定时任务。

例子中,选项-r表示删除所有定时任务。选项-i表示在删除前进行再次确定,输入y或者Y才能真正删除。

7备份我们设置的用户任务调度配置文件。

8系统任务调度的使用举例。

系统任务调度与用户任务调度不一样,需要直接在/etc/crontab里面配置,如果需要指定用户,还需要在执行命令前指定用户名。通过crontab -l 命令是查看不到系统任务调度任务的。

什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。

这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现<bean id="cronTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean" >

<property name="jobDetail" ref="schedulerJobDetail"/>

<property name="cronExpression">

<value>0/10 </value>

</property>

中cronExpression是关键,如果可以动态设置cronExpression的值,也就说如果我们可以直接调用CronTriggerBean中设置cronExpression的方法,就可以顺利解决问题了。

熟悉1的朋友可以跳过不看,下面2、3是动态定时任务的具体实现。

1. Quartz在Spring中的简单配置

Spring配置文件:

<bean id="schedulerJobDetail" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="scheduleInfoAction"/>

<property name="targetMethod" value="simpleJobTest"/>

<property name="concurrent" value="false"/>

</bean>

<bean id="cronTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean" >

<property name="jobDetail" ref="schedulerJobDetail"/>

<property name="cronExpression">

<value>0/10 </value>

</property>

</bean>

<bean id="schedulerFactory" class="orgspringframeworkschedulingquartzSchedulerFactoryBean">

<property name="triggers">

<list>

<ref local="cronTrigger"/>

</list>

</property>

</bean>

在上面的配置中设定了

① targetMethod: 指定需要定时执行scheduleInfoAction中的simpleJobTest()方法

② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。

③ cronExpression:0/10 表示每10秒执行一次,具体可参考附表。

④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。

scheduleInfoAction中的simpleJobTest()方法

注意:此方法没有参数,如果scheduleInfoAction有两个方法simpleJobTest()和simpleJobTest(String argument),则spring只会去执行无参的simpleJobTest()

public void simpleJobTest() {

logwarn("uh oh, Job is scheduled !'" + "' Success");

}

2.Quartz在Spring中动态设置cronTrigger方法一

Spring配置文件:

<bean id="scheduleInfoAction" class="comlivelyhappyoajobswebappactionScheduleInfoAction">

<property name="scheduler" ref="schedulerFactory"/>

<property name="scheduleInfoManager" ref="scheduleInfoManager"/>

</bean>

<bean id="schedulerJobDetail" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="scheduleInfoAction"/>

<property name="targetMethod" value="reScheduleJob"/>

<property name="concurrent" value="false"/>

</bean>

<bean id="cronTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean" >

<property name="jobDetail" ref="schedulerJobDetail"/>

<property name="cronExpression">

<value>0/10 </value>

</property>

</bean>

<bean id="schedulerFactory" class="orgspringframeworkschedulingquartzSchedulerFactoryBean">

<property name="triggers">

<list>

<ref local="cronTrigger"/>

</list>

</property>

</bean>

scheduleInfoAction中的reScheduleJob ()方法及相关方法

① reScheduleJob读取数据库,获得自定义定时器调度时间():

private void reScheduleJob() throws SchedulerException, ParseException {

// 运行时可通过动态注入的scheduler得到trigger

CronTriggerBean trigger = (CronTriggerBean) schedulergetTrigger(

"cronTrigger", SchedulerDEFAULT_GROUP);

String dbCronExpression = getCronExpressionFromDB();

String originConExpression = triggergetCronExpression();

// 判断从DB中取得的任务时间(dbCronExpression)和现在的quartz线程中的任务时间(originConExpression)是否相等

// 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob

if(!originConExpressionequalsIgnoreCase(dbCronExpression)){

triggersetCronExpression(dbCronExpression);

schedulerrescheduleJob("cronTrigger", SchedulerDEFAULT_GROUP, trigger);

}

// 下面是具体的job内容,可自行设置

// executeJobDetail();

}

② getCronExpressionFromDB():从数据库中获得dbCronExpression的具体代码,由于使用了scheduleInfoManager,所以要在定义相应的setter方法

private String getCronExpressionFromDB(){

String sql="from ScheduleInfo scheduleInfo where 1=1 ";

sql=sql+" and scheduleInfoinfoId = '"+"1" + "'";

List scheduleList = scheduleInfoManagerqueryScheduleInListBySql(sql);

ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleListget(0);

String dbCronExpression = scheduleInfogetCronExpression();

return dbCronExpression;

}

③ 在spring配置文件的scheduleInfoAction配置了相应的property(scheduler/ scheduleInfoManager),要为其设置setter方法

private Scheduler scheduler;

// 设值注入,通过setter方法传入被调用者的实例scheduler

public void setScheduler(Scheduler scheduler) {

thisscheduler = scheduler;

}

private ScheduleInfoManager scheduleInfoManager;

// 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager

public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){

thisscheduleInfoManager = scheduleInfoManager;

}

3. Quartz在Spring中动态设置cronTrigger方法二

在上面的2中我们可以看到,尽管已经可以动态进行rescheduleJob了,不过依然需要我们设置一个cronExpression,如果尝试一下拿掉spring配置中的

<property name="cronExpression">

<value>0/10 </value>

</property>

则容器(如tomcat)启动时会报错。

实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的dbCronExpression,然后定时执行一个job,而不希望配置初始的cronExpression ,观察下面的CronTriggerBean,考虑到cronExpression需要初始化,如果设定一个类InitializingCronTrigger继承CronTriggerBean,然后在这个类中做一些读取DB的初始化工作(设置cronExpression),问题就可以解决了。

Spring配置文件:

<bean id="scheduleInfoAction" class="comlivelyhappyoajobswebappactionScheduleInfoAction">

<property name="scheduler" ref="schedulerFactory"/>

<property name="scheduleInfoManager" ref="scheduleInfoManager"/>

</bean>

<bean id="schedulerJobDetail" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="scheduleInfoAction"/>

<property name="targetMethod" value="reScheduleJob"/>

<property name="concurrent" value="false"/>

</bean>

<bean id="cronTrigger" class="comlivelyhappyoajobswebappactionScheduleInfoActionInitializingCronTrigger">

<property name="jobDetail" ref="schedulerJobDetail"/>

<!--<property name="cronExpression">

<value>0/10 </value>

</property>-->

<property name="scheduleInfoManager" ref="scheduleInfoManager"/>

</bean>

<bean id="schedulerFactory" class="orgspringframeworkschedulingquartzSchedulerFactoryBean">

<property name="triggers">

<list>

<ref local="cronTrigger"/>

</list>

</property>

</bean>

InitializingCronTrigger中的相关方法

注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中)

注意InitializingCronTrigger必须extends CronTriggerBean

public class InitializingCronTrigger extends CronTriggerBean implements Serializable {

private ScheduleInfoManager scheduleInfoManager;

// 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager

public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){

thisscheduleInfoManager = scheduleInfoManager;

// 因为在getCronExpressionFromDB使用到了scheduleInfoManager,所以

// 必须上一行代码设置scheduleInfoManager后进行getCronExpressionFromDB

String cronExpression = getCronExpressionFromDB (); // ①

// 因为extends CronTriggerBean ,此处调用父类方法初始化cronExpression

setCronExpression(cronExpression); // ②

}

private String getCronExpressionFromDB(){

String sql="from ScheduleInfo scheduleInfo where 1=1 ";

sql=sql+" and scheduleInfoinfoId = '"+"1" + "'";

List scheduleList = scheduleInfoManagerqueryScheduleInListBySql(sql);

ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleListget(0);

String dbCronExpression = scheduleInfogetCronExpression();

return dbCronExpression;

}

……

}

附表:

"0 0 12 " 每天中午12点触发

"0 15 10 " 每天上午10:15触发

"0 15 10 " 每天上午10:15触发

"0 15 10 " 每天上午10:15触发

"0 15 10 2005" 2005年的每天上午10:15触发

"0 14 " 在每天下午2点到下午2:59期间的每1分钟触发

"0 0/5 14 " 在每天下午2点到下午2:55期间的每5分钟触发

"0 0/5 14,18 " 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

"0 0-5 14 " 在每天下午2点到下午2:05期间的每1分钟触发

"0 10,44 14 3 WED" 每年三月的星期三的下午2:10和2:44触发

"0 15 10 MON-FRI" 周一至周五的上午10:15触发

"0 15 10 15 " 每月15日上午10:15触发

"0 15 10 L " 每月最后一日的上午10:15触发

"0 15 10 6L" 每月的最后一个星期五上午10:15触发

"0 15 10 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发

"0 15 10 6#3" 每月的第三个星期五上午10:15触发

每隔5秒执行一次:/5

每隔1分钟执行一次:0 /1

每天23点执行一次:0 0 23

每天凌晨1点执行一次:0 0 1

每月1号凌晨1点执行一次:0 0 1 1

每月最后一天23点执行一次:0 0 23 L

每周星期天凌晨1点实行一次:0 0 1 L

至于每个符号 看看例子就好了很简单了

以上就是关于如何在quartz的job任务中 *** 作数据库全部的内容,包括:如何在quartz的job任务中 *** 作数据库、Linux下定时任务(系统任务调度、用户任务调度)crontab使用详解、spring cron配置每几分钟怎么设置等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9351692.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存