`
sundoctor
  • 浏览: 325558 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Quartz任务监控管理

阅读更多

Quartz任务监控管理,类似Windows任务管理器,可以获得运行时的实时监控,查看任务运行状态,动态增加任务,暂停、恢复、移除任务等。对于动态增加任务,可以参加我的前一篇文章《Quartz如何在Spring动态配置时间》,本文在前文的基础上扩展,增加暂停、恢复、移除任务等功能,实现Quartz任务监控管理。


先看一下最终实现实现效果,只有两个页面 ,如下

在这个页面查看任务实时运行状态,可以暂停、恢复、移除任务等


在这个页面可以动态配置调度任务。


实现任务监控,必须能将数据持久化,这里采用数据库方式,Quartz对任务的数据库持久化有着非常好的支持。我在这里采用quartz 2.2.1,在Quartz发行包的docs\dbTables目录包含有各种数据库对应脚本,我用的是H2,所以选用tables_h2.sql建表。


1.配置applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xsi:schemaLocation="
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
   http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    " >
  
   <context:component-scan base-package="com.sundoctor">
   		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>

	
	<!-- 使用H2内存数据库并创建quartz数据库表 -->
    <jdbc:embedded-database id="dataSource" type="H2">
        <jdbc:script location="classpath:db/tables_h2.sql"/>       
    </jdbc:embedded-database>	
	
	<!--Hibernate SessionFatory-->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
	    <property name="dataSource" ref="dataSource"/>
		<property name="packagesToScan">
			<list>
				<value>com.sundoctor.example.model</value>				
			</list>
		</property>	
	    <property name="hibernateProperties">
	        <props>
	            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
	            <prop key="hibernate.show_sql">true</prop>
	            <prop key="hibernate.format_sql">true</prop>				
				<prop key="hibernate.hbm2ddl.auto">update</prop>        
	        </props>
	    </property>
	</bean>	
	
	<!--Hibernate TransactionManager-->
	<bean id="transactionManager"  class="org.springframework.orm.hibernate4.HibernateTransactionManager">
	    <property name="sessionFactory" ref="sessionFactory"/>
	</bean>		

	<!-- 使用annotation定义事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />		

</beans>

 

配置Quartz,也分两步
1、配置quartz. properties

…
org.quartz.jobStore.misfireThreshold = 60000
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#org.quartz.jobStore.useProperties = true
org.quartz.jobStore.tablePrefix = QRTZ_  
org.quartz.jobStore.isClustered = false  org.quartz.jobStore.maxMisfiresToHandleAtATime=1


在这里采用JobStoreTX,将任务持久化到数据中,而不再是简单的内存方式:RAMJobStore

2、配置applicationContext-quartz.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
        <property name="dataSource" ref ="dataSource" />       
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
        <property name="configLocation" value="classpath:quartz.properties"/>			
    </bean>
    
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" >
        <property name="jobClass">
            <value>com.sundoctor.example.service.MyQuartzJobBean</value>
        </property>
       <property name="durability" value="true" />	
    </bean>
	 
</beans>

 

到些,相关配置全部完成,对于配置的具体描述,可以参加我的前一篇文章《Quartz如何在Spring动态配置时间》

实现任务动态添加配置

请参考com.sundoctor.quartz.service.SchedulerServiceImpl.java中的各种schedule方法,在《Quartz如何在Spring动态配置时间》有具体描述。在这里说一下:
添加一个Job在表qrtz_job_details插入一条记录
添加一个Simple Trigger在表qrtz_simple_triggers插入一条记录
添加一个Cron Trigger 在表qrtz_cron_triggers插入一条记录
添加Simple Trigger和Cron Trigger都会同进在表qrtz_triggers插入一条记录,开始看的第一个页面调度任务列表数据就是从qrtz_triggers表获取

实现任务实时监控,暂停、恢复、移除任务等
在com.sundoctor.quartz.service.SchedulerServiceImpl.java类中

暂停任务

	@Override
	public void pauseTrigger(String triggerName, String group) {
		try {
			scheduler.pauseTrigger(new TriggerKey(triggerName, group));// 停止触发器
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}

 

恢复任务

	@Override
	public void resumeTrigger(String triggerName, String group) {
		try {
			scheduler.resumeTrigger(new TriggerKey(triggerName, group));// 重启触发器
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}


移除任务

	@Override
	public boolean removeTrigdger(String triggerName, String group) {
		TriggerKey triggerKey = new TriggerKey(triggerName, group);
		try {
			scheduler.pauseTrigger(triggerKey);// 停止触发器
			return scheduler.unscheduleJob(triggerKey);// 移除触发器
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}



其它类的实现请参加《Quartz如何在Spring动态配置时间》,那里有具体说明。

到此,基本简单实现了Quartz任务监控管理。其实面这里只是实现了Trigger任务的监控管理,没有实现Job任务的监控管理,实现Job任务的监控管理跟Trigger差不多。用Quartz可以很方便实现多样化的任务监控管理,Trigger任务和Job任务都可进行分组管理。

Quartz很强大,也很简单,只有想不到的,没有做不到的,人有多大胆,地有多高产。

 

分享到:
评论
56 楼 lyg 2010-01-27  
firstpub7603 写道
新手求教:
示例的后台数据表是自动创建还是手工创建的,如果是自动创建,为什么我部署启动后,后台报找不到数据表的错误?如果是手工创建,请告诉我表结构,谢谢!

手工创建
55 楼 firstpub7603 2010-01-27  
新手求教:
示例的后台数据表是自动创建还是手工创建的,如果是自动创建,为什么我部署启动后,后台报找不到数据表的错误?如果是手工创建,请告诉我表结构,谢谢!
54 楼 ljj832003 2009-11-06  
楼主,按照你的例子作了下
报如下的错误
java.lang.RuntimeException: org.quartz.JobPersistenceException: Couldn't store trigger '8defd250-ae9e-41d3-ab6a-0467c5658424' for 'jobDetail' job:The job (DEFAULT.jobDetail) referenced by the trigger does not exist. [See nested exception: org.quartz.JobPersistenceException: The job (DEFAULT.jobDetail) referenced by the trigger does not exist.]
at cibs.timer.quartz.impl.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:94)
at cibs.timer.quartz.impl.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:62)
at cibs.timer.quartz.impl.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:57)
at cibs.timer.quartz.impl.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:53)
at test.CIBSTimerServiceTest.test(CIBSTimerServiceTest.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.quartz.JobPersistenceException: Couldn't store trigger '8defd250-ae9e-41d3-ab6a-0467c5658424' for 'jobDetail' job:The job (DEFAULT.jobDetail) referenced by the trigger does not exist. [See nested exception: org.quartz.JobPersistenceException: The job (DEFAULT.jobDetail) referenced by the trigger does not exist.]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1246)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$5.execute(JobStoreSupport.java:1152)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$40.execute(JobStoreSupport.java:3688)
at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:244)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInLock(JobStoreSupport.java:3684)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1148)
at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:779)
at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:276)
at cibs.timer.quartz.impl.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:90)
... 27 more
Caused by: org.quartz.JobPersistenceException: The job (DEFAULT.jobDetail) referenced by the trigger does not exist.
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1207)
... 35 more
我的配置都是完全按照你的例子上来的应该不会有误,请问这个错误是什么原因引起的?

public void schedule(String name, CronExpression cronExpression,String group) {
if (name == null || name.trim().equals("")) {
name = UUID.randomUUID().toString();
}else{
//在名称后添加UUID,保证名称的唯一性
name +="&"+UUID.randomUUID().toString();
}

try {
scheduler.addJob(jobDetail, true);

CronTrigger cronTrigger = new CronTrigger(name, group, jobDetail.getName(),
Scheduler.DEFAULT_GROUP);
cronTrigger.setCronExpression(cronExpression);
scheduler.scheduleJob(cronTrigger);//运行到这里就报错
scheduler.rescheduleJob(cronTrigger.getName(), cronTrigger.getGroup(), cronTrigger);

} catch (SchedulerException e) {
throw new RuntimeException(e);
}
}

53 楼 sundoctor 2009-10-06  
zxt1985 写道
非常感谢lz,这样果然可以,但我听网上好多网友说,这样的静态配置会出问题,不知是否有此情况发生?


绝对不会出问题,简单应用用静态配置就可以了。
52 楼 zxt1985 2009-10-06  
非常感谢lz,这样果然可以,但我听网上好多网友说,这样的静态配置会出问题,不知是否有此情况发生?
51 楼 sundoctor 2009-09-30  
Quartz任务监控的完善版,请看《Quartz 任务监控 (2)》http://sundoctor.iteye.com/admin/blogs/480405
50 楼 sundoctor 2009-09-30  
引用
我的意思是想,如果数据库里没有trigger,那就创建一个,如果没有job,那也新建一个,直接在spring初始化的时候就操作,这样就不用我们认为的去添加trigger和job了,tomcat启动后就自动执行了。这样不知道会出问题不?


根据你以上的需求,你只要用spring+quartz的简单配置就能满足了,不用持久化,也不用序列化,你用静态配置就行了,《quartz任务监控》说的是动态配置任务可能并不适合你了。

applicationContext-quartz.xml的配置
<bean  id="schedulerTrigger" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>				
<ref bean="trigger1"/>				  		 
<ref bean="trigger2"/>
</list>
</property>
</bean>

<!-- 每天凌晨1点执行 -->
<bean id="jobDetail1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="xxxService1" />
<property name="targetMethod" value="testMethod1" />
</bean>	
<bean id="trigger1" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetail1" />
<property name="cronExpression" value="0 0 1 ? * * *" />
</bean> 

<!--执行50次结束-->
<bean id="jobDeail2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="xxxService2" />
<property name="targetMethod" value="testMethod2" />
</bean>	
<bean id="trigger2" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobDeail2" />     
<property name="startDelay" value = "4"/>     
<property name="repeatCount" value = "50" />       
<property name="repeatInterval" value = "1000" />    
</bean>


xxxService1是你的业务类,不用实现序列化接口,testMethod1是xxxService1的一个方法,执行调试任务的方法。

你的需求只需要这样简单配置就行了,tomcat启动后就会触发trigger1,trigger2了,trigger1会在每天1点触发xxxService1的testMethod1方法,trigger2会在服务启动后触发xxxService2的testMethod2方法,执行50次结束。因为不用持久化了,你写的所有类都不用实现序列化接口,也不会出现事务问题了,也不出现你所说的多个tirgger问题了,你前面所说的所有问题都没有了。
49 楼 sundoctor 2009-09-30  
引用
看我的初始化方法这样处理是否可以?但我做了测试,好像还是不行,把init-method="init" 去掉,另外一台机器就没问题了。我怀疑也是集群的事,同一个trigger不支持多个服务器访问。不知道LZ能有什么好的建议?


请参考《quatrz 任务监控管理 (2)》http://www.iteye.com/topic/480405的实现中,init这个方法己经从SchedulerServiceImpl去掉了,不再需要。同一个trigger多个服务器访问属于集群,quartz是支持集群的,但是在配置上有点差别,你的应用是需要集群吗
48 楼 zxt1985 2009-09-30  
根据lz你的方法重新修改了一下上上个问题:能否在init方法中这样写?
/**
	 * 初始化job
	 * @throws SchedulerException
	 */
	public void init() throws SchedulerException{
		System.out.println("Job init start......");
		JobDetail job = scheduler.getJobDetail("jobDetail", "DEFAULT");
		if(job==null){
			scheduler.addJob(jobDetail, true);
		}
		try {
			Trigger trigger = scheduler.getTrigger("MYTRIGGER", "DEFAULT");   
			if(trigger == null){   
				schedule("MYTRIGGER", "0/30 * 9-18 ? * MON-FRI *");     
			}else{   
				scheduler.rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);   
			} 
			
		} catch (SchedulerException e) {
			log.error("the schedulerService.getScheduler().getTriggerState() is error!"+e.getMessage());
		}
		System.out.println("Job init end......");
	}	


我的意思是想,如果数据库里没有trigger,那就创建一个,如果没有job,那也新建一个,直接在spring初始化的时候就操作,这样就不用我们认为的去添加trigger和job了,tomcat启动后就自动执行了。这样不知道会出问题不?
47 楼 zxt1985 2009-09-30  
LZ:我发现spring的事务与实现序列化有冲突,当我把实现序列化的service加上事务时,启动tomcat老报什么不能类型转换的错误,去掉序列化就不出问题了,但是,这样我的job所依赖的service启不是不能用了?能有好的方法:
即可以加事务,又不影响quartz的任务执行?包括使用hibernateTempalte。
46 楼 zxt1985 2009-09-30  
/**
  * 初始化job
  * @throws SchedulerException
  */
 public void init() throws SchedulerException{
  System.out.println(&quot;Job init start......&quot;);
  JobDetail job = scheduler.getJobDetail(&quot;jobDetail&quot;, &quot;DEFAULT&quot;);
  if(job==null){
   scheduler.addJob(jobDetail, true);
  }
  try {
   int state = scheduler.getTriggerState(&quot;MYTRIGGER&quot;, &quot;DEFAULT&quot;);
   if(state==-1){
    schedule(&quot;MYTRIGGER&quot;, &quot;0/30 * 9-18 ? * MON-FRI *&quot;); 
   }else if(state==3){
    boolean removeTrigger =removeTrigdger(&quot;MYTRIGGER&quot;, &quot;DEFAULT&quot;);
    boolean removeJob = scheduler.deleteJob(&quot;jobDetail&quot;, &quot;DEFAULT&quot;);
    if(removeTrigger &amp;&amp; removeTrigger){
     scheduler.addJob(jobDetail, true);
     schedule(&quot;MYTRIGGER&quot;, &quot;0/30 * 9-18 ? * MON-FRI *&quot;);
    }
   }
  } catch (SchedulerException e) {
   log.error(&quot;the schedulerService.getScheduler().getTriggerState() is error!&quot;+e.getMessage());
  }
  System.out.println(&quot;Job init end......&quot;);
 } 



LZ这是我的那个初始化方法,在applicationContext-quartz.xml中配了
<bean id="schedulerService" class="com.gamutsoft.itsm.service.quartz.SchedulerServiceImpl" init-method="init">
		<property name="scheduler" ref="quartzScheduler" /> 
		<property name="jobDetail" ref="jobDetail" /> 
	</bean>


看我的初始化方法这样处理是否可以?但我做了测试,好像还是不行,把init-method="init" 去掉,另外一台机器就没问题了。我怀疑也是集群的事,同一个trigger不支持多个服务器访问。不知道LZ能有什么好的建议?
45 楼 sundoctor 2009-09-29  
引用

你好,请问你的那个quartzMonitor的源码能否处理并发的情况?我现在就出现这种问题了,我们用的是同一个数据库,当把项目部署到服务器上时,启动tomcat,我设了<property name="startupDelay" value="60"/>,这个时候数据库的表qtz_cro_trigger和qtz_triggers有记录,这个时候我在本机又启动 tomcat,这个时候出问题了,服务器的tomcat报错,错误如下:
2009-09-28 10:45:00,001 ERROR [org.springframework.scheduling.quartz.LocalDataSourceJobStore] - Error retrieving job, setting trigger state
to ERROR.

这是错误,是因为你启动的两个tomcat服务中的得到的两个SesssionFactory实例是不一样的,在SchedulerServiceImpl中的
	@PostConstruct
	public void init() throws SchedulerException{
		logger.info("init start....................");
		scheduler.addJob(jobDetail, true);	
		logger.info("init end.......................");		
	}

的init()会在启动时将当前的SesssionFactory更新到Job中。第一个tomcat启动将自己的SesssionFactory更新到Job中,第二个tomcat启动后又将自己的SesssionFactory更新到Job中,这样第一个tomcat的Job取到的SesssionFactory己经不自己的那个SesssionFactory,所以会报这个异常。这个问题己经解决,请参数《quatrz 任务监控管理 (2)》http://www.iteye.com/topic/480405, 可以并发运行了。但是我觉得这样并不是简单的并发运行,而是 quartz集群,关于quartz集群的问题,等我有空会简单写一个。

引用

我用的是quartz-all-1.6.5.jar。这些代码都运行正常,就是现在出了一个并发,不能同时2台机器操作同一个数据库,我们用的是 mysql。我想问问LZ,有什么办法能控制qrtz_cron_triggers,qrtz_triggers,qrtz_job_detail这3张表,每次只有一条记录,因为,我发现若有多条记录,那就会同时运行多次,比如有3条记录,设置时间是0/30**?**的话,过30秒后就同时有3条打印值。

有三条记录,那是因为你加了三条,有三条记录,当然会打印三打值。要一条记录,你只加一条就好了。quartz不会自动给你加记录的,有点象废话了。

引用

2.还有一个问题:数据库表qrtz_triggers有一个trigger_state字段,这个字段表示触发器的状态,如果为error则任务不会运行,上面出现并发后,这个字段的值就为error了,这个问题你知道怎么解决吗?我的MainTest的想法是:如果数据库里没有以 triggerName="MYTRIGGER" triggerGroup="DEFAULT"的记录时,我就schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *");往里面加一条,如果里面这条记录的状态state==3(也就是error)的时候,我就把 qrtz_cron_trigger,qrtz_job_detail的这条记录删了,重新再加一条。不知道我思路是否正确?

如果数据库里没有以 triggerName="MYTRIGGER" triggerGroup="DEFAULT"的记录时,可以这么判断
Trigger trigger = schedulerService.getScheduler().getTrigger("MYTRIGGER", "DEFAULT");
if(trigger == null){
    schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *"); 
}


不管trigger处于任何状态,你调用scheduler.rescheduleJob就可以恢复执行了
Trigger trigger = schedulerService.getScheduler().getTrigger("MYTRIGGER", "DEFAULT");
if(trigger == null){
    schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *"); 
}else{
    schedulerService.getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
}


引用

3.第3个问题:请问能否人工的控制trigger_state状态?如何往MyQuartzJobBean类里面传参数?就是从前台界面传进来。是否需要在配置文件里配置?

trigger_state好象不能人工控制,这个我也不太清楚。

44 楼 zxt1985 2009-09-28  
你好,请问你的那个quartzMonitor的源码能否处理并发的情况?我现在就出现这种问题了,我们用的是同一个数据库,当把项目部署到服务器上时,启动tomcat,我设了<property name="startupDelay" value="60"/>,这个时候数据库的表qtz_cro_trigger和qtz_triggers有记录,这个时候我在本机又启动tomcat,这个时候出问题了,服务器的tomcat报错,错误如下:
2009-09-28 10:45:00,001 ERROR [org.springframework.scheduling.quartz.LocalDataSourceJobStore] - Error retrieving job, setting trigger state
to ERROR.
org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: Could not find a SessionFactory named:
null [See nested exception: java.io.InvalidObjectException: Could not find a SessionFactory named: null]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1397)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggerFired(JobStoreSupport.java:2879)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$38.execute(JobStoreSupport.java:2847)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3760)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.triggerFired(JobStoreSupport.java:2841)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:342)
Caused by: java.io.InvalidObjectException: Could not find a SessionFactory named: null
at org.hibernate.impl.SessionFactoryImpl.readResolve(SessionFactoryImpl.java:612)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadResolve(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at java.util.HashMap.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.getObjectFromBlob(StdJDBCDelegate.java:3476)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:907)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1380)
... 5 more
当我把数据库表qrtz_triggers和qrtz_cron_triggers以及qrtz_job_details中的记录全部删除后,再启动服务器的tomcat,这个时候没问题了,但是千万别再在本机或其他的机器启动tomcat访问这个数据库,否则,出同样的问题,我猜是并发的问题,因为当服务器的那个job正在访问的同时,本机又接着访问,这样本机就会再往数据库qrtz_job_detail里添加一条记录,这样,服务器那端出问题了……不知道我理解的是否正确,麻烦LZ能帮我看看呗,非常感谢了,我下面附上我的代码:
applicationContext-quartz.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
<import resource="applicationContext-service.xml" />
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" >
<property name="dataSource"> 
<ref bean="dataSource" /> 
</property>
<property name="applicationContextSchedulerContextKey"  value="applicationContextKey" />
<property name="configLocation" value="classpath:quartz.properties"/>

<!-- 延时启动,这个很重要,必须要有足够长的时间让你的应用先启动完成后再让 Scheduler启动,
这里设置60秒,如果你的应用启动时间较长,要相应增加startupDelay的时间-->
<property name="startupDelay" value="60"/>
<!-- 不自动启动 -->
<!--<property name="autoStartup" value="false" />-->
<!-- Run every 5 minute --> 
<!-- <property name="repeatInterval" value="300000" />--> 
</bean>

<bean id="schedulerService" class="com.gamutsoft.itsm.service.quartz.SchedulerServiceImpl" init-method="init">
<property name="scheduler" ref="quartzScheduler" />
<property name="jobDetail" ref="jobDetail" />
</bean>

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.gamutsoft.itsm.service.jobbean.MyQuartzJobBean</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="simpleService">
<ref bean="simpleService" />
</entry>
</map>
</property>
</bean>

</beans>

applicationContext-commen.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- 定义数据源Bean,使用C3P0数据源实现 -->
<bean id="dataSource" destroy-method="close"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 指定连接数据库的驱动 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<!-- 指定连接数据库的URL -->
<property name="jdbcUrl"
value="jdbc:mysql://192.168.20.108:3306/itsm?useUnicode=true&amp;characterEncoding=utf8"/>
<!-- 指定连接数据库的用户名 -->
<property name="user" value="root"/>
<!-- 指定连接数据库的密码 -->
<property name="password" value="root"/>
<!-- 指定连接数据库连接池的最大连接数 -->
<property name="maxPoolSize" value="10"/>
<!-- 指定连接数据库连接池的最小连接数 -->
<property name="minPoolSize" value="1"/>
<!-- 指定连接数据库连接池的初始化连接数 -->
<property name="initialPoolSize" value="1"/>
<!-- 指定连接数据库连接池的连接的最大空闲时间 -->
<property name="maxIdleTime" value="30"/>
</bean>
<!-- 定义Hibernate的SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 依赖注入数据源,注入上面定义的dataSource -->
<property name="dataSource">
<ref bean="dataSource" />
</property>

<property name="mappingLocations">      
         <value>classpath*:/com/gamutsoft/itsm/model/*/*.hbm.xml</value>
     </property>

<!-- property name="mappingResources">
<list>
<以下用来列出Hibernate映射文件 >
<value>com/gamutsoft/itsm/model/system/User.hbm.xml</value>
<value>com/gamutsoft/itsm/model/system/Role.hbm.xml</value>
<value>com/gamutsoft/itsm/model/system/Function.hbm.xml</value>
</list>
</property -->
<!-- 定义Hibernate的SessionFactory的属性 -->
<property name="hibernateProperties">
<props>
<!-- 指定数据库方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<!-- 是否根据需要每次自动创建数据库 -->
<!-- prop key="hibernate.hbm2ddl.auto">update</prop -->
<!-- 显示Hibernate持久化操作所生成的SQL -->
<prop key="hibernate.show_sql">false</prop>
<!-- 将SQL脚本进行格式化后再输出 -->
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 -->
<!-- 该类实现PlatformTransactionManager接口,是针对Hibernate的特定实现-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- 配置HibernateTransactionManager时需要依注入SessionFactory的引用 -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 配置事务切面Bean,指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 用于配置详细的事务语义 -->
<tx:attributes>
<!-- 所有以'get'开头的方法是read-only的 -->
<tx:method name="get*" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.RuntimeException"/>
<!-- tx:method name="*" rollback-for="java.lang.Throwable" read-only="false" propagation="REQUIRED"/-->
</tx:attributes>
</tx:advice>
</beans>

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<import resource="applicationContext-common.xml"/>
<import resource="applicationContext-dao.xml"/>
<import resource="applicationContext-service.xml"/>

<import resource="applicationContext-quartz.xml"/>
</beans>

applicationContext-dao.xml:这个配置文件就不贴了,这个配置文件没问题下面我贴
applicationContext-service.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

        <bean id="simpleService" class="com.gamutsoft.itsm.service.jobbean.SimpleService">
<property name="itsmSlaService" ref="itsmSlaService" />
<property name="itsmMessageService" ref="itsmMessageService" />
<property name="taskService" ref="taskService" />

<property name="itsmRoleDAO">
<ref bean="itsmRoleDAO" />
</property>
<property name="incidentDAO">
<ref bean="incidentDAO" />
</property>
<property name="baseRequestDAO">
<ref bean="baseRequestDAO" />
</property>
<property name="itsmIncRemainderSessionDAO">
<ref bean="itsmIncRemainderSessionDAO" />
</property>
       </bean>
      <bean id="taskService" class="com.gamutsoft.itsm.service.incident.TaskService">
<property name="taskDAO">
<ref bean="taskDAO" />
</property>
</bean>
<bean id="itsmSlaService" class="com.gamutsoft.itsm.service.system.ItsmSlaService">
<property name="itsmIncSlaDAO">
<ref bean="itsmIncSlaDAO" />
</property>
<property name="itsmSlaDAO">
<ref bean="itsmSlaDAO" />
</property>
<property name="itsmWorkdayConfigDAO">
<ref bean="itsmWorkdayConfigDAO" />
</property>
</bean>
<bean id="itsmMessageService" class="com.gamutsoft.itsm.service.system.ItsmMessageService">
<property name="itsmMessageDAO">
<ref bean="itsmMessageDAO" />
</property>
</bean>
......等等<bean>配置
</beans>

这些配置都没问题,包括我依赖的DAO,这些DAO都实现序列化,包括依赖的service:itsmSlaService,itsmMessageService,taskService。我下面把其中一个DAO和service类贴过来

ItsmSlaService :
public class ItsmSlaService implements java.io.Serializable{
         //这几个依赖的DAO都实现序列化了,而且用的都是sessionFactory的HibernateTemplate
private ItsmIncSlaDAO itsmIncSlaDAO;
private ItsmSlaDAO itsmSlaDAO;
private ItsmWorkdayConfigDAO itsmWorkdayConfigDAO;

private final static Integer WORKDAYDEFAULTID = 1;
         .......
}

ItsmSlaDAO :
public class ItsmSlaDAO implements java.io.Serializable {
private static final Log log = LogFactory.getLog(ItsmSlaDAO.class);

private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

private HibernateTemplate getHibernateTemplate(){
HibernateTemplate  hibernateTemplate = new HibernateTemplate(sessionFactory);
return hibernateTemplate;
}

protected void initDao() {
// do nothing
}

public ItsmSla findDefautSla(){
ItsmSla sla = new ItsmSla();
String queryString = "from ItsmSla as model where model."
+ DEFAULT_SLA + "= 1";
List<ItsmSla> slas = getHibernateTemplate().find(queryString);
Iterator<ItsmSla> ite = slas.iterator();
if(slas!=null&(slas.size()==1)){
sla = ite.next();
}
return sla;
}
       ........
}


quartz.properties:

org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

org.quartz.jobStore.misfireThreshold = 60000

#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#org.quartz.jobStore.useProperties = true
org.quartz.jobStore.tablePrefix = QRTZ_ 
org.quartz.jobStore.isClustered = false 
org.quartz.jobStore.maxMisfiresToHandleAtATime=1

simpleService:
public class SimpleService implements Serializable{

private static final long serialVersionUID = 122323233244334343L;
private static Logger log = Logger.getLogger(SimpleService.class);


//事件
private IncidentDAO incidentDAO;
public void setIncidentDAO(IncidentDAO incidentDAO) {
this.incidentDAO = incidentDAO;
}
//公共请求
private BaseRequestDAO baseRequestDAO ;
public void setBaseRequestDAO(BaseRequestDAO baseRequestDAO) {
this.baseRequestDAO = baseRequestDAO;
}
//sla
private ItsmSlaService itsmSlaService;
public void setItsmSlaService(ItsmSlaService itsmSlaService) {
this.itsmSlaService = itsmSlaService;
}
//消息
private ItsmMessageService itsmMessageService;
public void setItsmMessageService(ItsmMessageService itsmMessageService) {
this.itsmMessageService = itsmMessageService;
}
//距目标时间的时长
private ItsmIncRemainderSessionDAO itsmIncRemainderSessionDAO;
public void setItsmIncRemainderSessionDAO(
ItsmIncRemainderSessionDAO itsmIncRemainderSessionDAO) {
this.itsmIncRemainderSessionDAO = itsmIncRemainderSessionDAO;
}
//用户
private ItsmRoleDAO itsmRoleDAO;
public void setItsmRoleDAO(ItsmRoleDAO itsmRoleDAO) {
this.itsmRoleDAO = itsmRoleDAO;
}

//任务
private TaskService taskService;
public void setTaskService(TaskService taskService) {
this.taskService = taskService;
}

public void schedulerMethod(){
//这里执行定时调度业务 

       System.out.println("in the method-->");
}
         ..........
}

MyQuartzJobBean :

public class MyQuartzJobBean extends QuartzJobBean {

private SimpleService simpleService;
public void setSimpleService(SimpleService simpleService) {
this.simpleService = simpleService;
}
 
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// Trigger trigger = context.getTrigger();
// String triggerName = trigger.getName();
//System.out.println("triggername=="+triggerName);
// if(triggerName.equals("MYTRIGGER")){
simpleService.schedulerMethod();
}
}

}
SchedulerService和SchedulerServiceImpl都是用的你写的。一模一样,我就不贴了,我把测试类放上来你看看吧:
MainTest:

public class MainTest {

/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext springContext = new ClassPathXmlApplicationContext("applicationContext.xml");
SchedulerServiceImpl schedulerService = (SchedulerServiceImpl)springContext.getBean("schedulerService");

//执行业务逻辑...

//设置高度任务
//每10秒中执行调试一次
// schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *");
// schedulerService.schedule("0/30 * * ? * * *");
try {
int state = schedulerService.getScheduler().getTriggerState("MYTRIGGER", "DEFAULT");
if(state==-1){
schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *");
}else if(state==3){
boolean removeTrigger = schedulerService.removeTrigdger("MYTRIGGER", "DEFAULT");
boolean removeJob = schedulerService.getScheduler().deleteJob("jobDetail", "DEFAULT");
if(removeTrigger && removeTrigger){
schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *");
}
}
} catch (SchedulerException e) {
System.out.println("the schedulerService.getScheduler().getTriggerState() is error!");
}}

我用的是quartz-all-1.6.5.jar。这些代码都运行正常,就是现在出了一个并发,不能同时2台机器操作同一个数据库,我们用的是mysql。我想问问LZ,有什么办法能控制qrtz_cron_triggers,qrtz_triggers,qrtz_job_detail这3张表,每次只有一条记录,因为,我发现若有多条记录,那就会同时运行多次,比如有3条记录,设置时间是0/30**?**的话,过30秒后就同时有3条打印值。
2.还有一个问题:数据库表qrtz_triggers有一个trigger_state字段,这个字段表示触发器的状态,如果为error则任务不会运行,上面出现并发后,这个字段的值就为error了,这个问题你知道怎么解决吗?我的MainTest的想法是:如果数据库里没有以triggerName="MYTRIGGER" triggerGroup="DEFAULT"的记录时,我就schedulerService.schedule("MYTRIGGER", "0/30 * * ? * * *");往里面加一条,如果里面这条记录的状态state==3(也就是error)的时候,我就把qrtz_cron_trigger,qrtz_job_detail的这条记录删了,重新再加一条。不知道我思路是否正确?
3.第3个问题:请问能否人工的控制trigger_state状态?如何往MyQuartzJobBean类里面传参数?就是从前台界面传进来。是否需要在配置文件里配置?

呵呵,我遇到的问题还挺多,有劳大家和LZ帮忙解决一下咯!非常感谢!
43 楼 sundoctor 2009-09-21  
wangyi2200 写道
有个问题想问一下,如果当任务执行的时间点上,正好服务器down掉或由于其他原因任务没有顺利完成
该如何自动或手动唤醒它,让他顺利执行呢?




//获取到Scheduler
Scheduler scheduler = ...;//(Scheduler)springContext.getBean("quartzScheduler");
//通过trigger name和trigger group得到SimpleTrigger 
SimpleTrigger trigger = (SimpleTrigger)scheduler.getTrigger("52f071d3-eebb-4308-abeb-9ce8ec58aba4", "DEFAULT");
//重新设置Trigger己经触发的次数
int timesTriggered = trigger.getTimesTriggered();
trigger.setTimesTriggered(timesTriggered > 0 ? timesTriggered -1 : 0);

//可选,重新设置开始触发时间
//trigger.setStartTime(startTime);
//可选,重新设置下次触发时间
//trigger.setNextFireTime(nextFireTime);
//等等,还有许多可选配置可以重新设置

//调用rescheduleJob重新调度tirgger
scheduler.rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);


这样即可恢复trigger执行
42 楼 wangyi2200 2009-09-21  
有个问题想问一下,如果当任务执行的时间点上,正好服务器down掉或由于其他原因任务没有顺利完成
该如何自动或手动唤醒它,让他顺利执行呢?

41 楼 sundoctor 2009-09-17  
wangyi2200 写道
嗯,感谢,又出现个问题:
public class QuartzBusinessDao implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(QuartzBusinessDao.class);
private SessionFactory sessionFactory;
  
    public void setSessionFactory(SessionFactory sessionFactory) { 
       this.sessionFactory = sessionFactory;
    } 
public void saveOrUpdateCatalogPromoTime(long catalogId){
HibernateTemplate  hibernateTemplate = new HibernateTemplate(sessionFactory);
Catalog catalog = (Catalog)hibernateTemplate.get(Catalog.class, catalogId);
System.out.println("success:"+catalog.getCatalogNo());
}
}
启动项目报错:
Couldn't store job: Unable to serialize JobDataMap for insertion into database because the value of property 'quartzBusinessDao' is not serializable: org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler [See nested exception: java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'quartzBusinessDao' is not serializable: org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler]


说quartzBusinessDao没有序列化,你己经 QuartzBusinessDao implements Serializable,我也看不出什么原因了。你可以先把qrtz_job_details对应jobDetail删除后再试试。
40 楼 wangyi2200 2009-09-17  
嗯,感谢,又出现个问题:
public class QuartzBusinessDao implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(QuartzBusinessDao.class);
private SessionFactory sessionFactory;
  
    public void setSessionFactory(SessionFactory sessionFactory) { 
       this.sessionFactory = sessionFactory;
    } 
public void saveOrUpdateCatalogPromoTime(long catalogId){
HibernateTemplate  hibernateTemplate = new HibernateTemplate(sessionFactory);
Catalog catalog = (Catalog)hibernateTemplate.get(Catalog.class, catalogId);
System.out.println("success:"+catalog.getCatalogNo());
}
}
启动项目报错:
Couldn't store job: Unable to serialize JobDataMap for insertion into database because the value of property 'quartzBusinessDao' is not serializable: org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler [See nested exception: java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'quartzBusinessDao' is not serializable: org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler]
39 楼 sundoctor 2009-09-16  
wangyi2200 写道
请教lz为何在
scheduler.scheduleJob(cronTrigger);
后要调用
scheduler.rescheduleJob(cronTrigger.getName(),cronTrigger.getGroup(), cronTrigger);
这里不是很明白
另外jobGroup一般会在何种场合区分使用


rescheduleJob是在重新设置了调度时间规则时才需要调用,在这里并不需要调用rescheduleJob,这是我在此画蛇添足了。

在quartz中tirgger通过name和jobGroup唯一确定一条记录,分组可以方便管理,就象一个大的团体分几个组一样,怎么样用,可以根据自己的不同需要灵活使用,我觉得只有你有非常多的jobDetail(比如好几百个jobDetail)时为管理方便才需要使用jobGroup,否则一般使用一个默认jobGroup就足够了。
38 楼 wangyi2200 2009-09-16  
请教lz为何在
scheduler.scheduleJob(cronTrigger);
后要调用
scheduler.rescheduleJob(cronTrigger.getName(),cronTrigger.getGroup(), cronTrigger);
这里不是很明白
另外jobGroup一般会在何种场合区分使用
37 楼 wangyi2200 2009-09-16  
上面的问题找到答案了,修改quartz.properties:
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

相关推荐

    quartz动态任务管理

    这个"quartz动态任务管理"源码包很可能是针对Quartz框架的实现,旨在帮助开发者更方便地管理和控制任务的生命周期。 Quartz的核心概念包括作业(Job)、触发器(Trigger)和计划程序(Scheduler)。作业是你要执行...

    基于SSM+quartz的定时任务管理demo

    为了方便管理和监控定时任务,可以开发一个Web界面,利用Quartz提供的API查询Job和Trigger信息,支持新增、修改、删除等操作。此外,还可以查看任务执行日志,以便于排查问题。 总结,本Demo旨在通过SSM+Quartz的...

    基于Spring和Quartz的任务调度监控管理平台设计源码

    本源码为基于Spring和Quartz的任务调度监控管理平台设计,共包含553个文件,其中css文件190个,png文件111个,java文件96个,js文件63个,sql文件22个,html文件20个,jsp文件17个,gif文件15个,xml文件9个,...

    Quartz定时任务图形界面的系统

    在本系统中,SpringMVC用于处理前端请求,实现与后端服务的交互,同时也可能利用Spring的依赖注入特性来管理Quartz任务相关的bean。 3. **MyBatis**: MyBatis是一个持久层框架,它简化了SQL操作,将SQL语句与Java...

    Quartz如何实现判断某个任务是否正在运行,在项目中用到的,已经测试过了

    Quartz是一款广泛应用于Java开发中的开源任务调度框架,它提供了强大的定时任务管理功能,支持复杂的调度策略和分布式部署。在实际项目中,有时我们需要判断一...通过上述步骤,你可以有效地管理和监控你的Quartz任务。

    定时任务quartz实现分组串行并行动态配置

    2. **分组管理**:Quartz允许我们为Job分配不同的组,这有助于分类和管理任务。我们可以在创建JobDetail时指定Job的组名,以便于后续的查询和操作。 3. **串行执行**:如果希望同一组内的Job按顺序执行,可以使用`...

    .net Quartz 任务调度平台源码

    5. **监控与管理**:提供了监控界面,可以查看当前运行的任务状态,包括任务的执行进度、异常情况等,方便进行问题排查和性能优化。 6. **日志记录**:任务执行过程中的信息会被记录下来,包括成功、失败、警告等,...

    WEB管理的Quartz定时任务

    在Web管理的Quartz定时任务中,我们通常会结合SpringMVC和MyBatis来构建一个完善的后台管理系统,以便于管理和监控定时任务。下面将详细介绍这个系统的组成部分和实现方式。 **1. Quartz简介** Quartz是Java平台上...

    Quartz.net作业调度自定义定时执行任务多任务执行c#

    总的来说,Quartz.NET为.NET开发者提供了一套强大且灵活的定时任务解决方案,使得系统可以自动执行各种业务逻辑,如订单管理和库存控制等,极大地提高了系统的自动化程度和效率。通过熟练掌握Quartz.NET,开发者可以...

    quartz任务调度使用手册

    Quartz任务调度是一款开源的Java定时任务框架,广泛应用于企业级应用系统中,用于执行周期性的后台任务。这款工具提供了一种灵活的方式来安排和管理任务,使得开发者无需在业务代码中处理时间相关的逻辑,而是通过...

    Quartz 定时任务web使用

    Quartz 是一个开源的作业调度框架,常用于Java应用程序中实现定时任务的管理。它提供了丰富的API和功能,使得开发者可以灵活地定义和控制任务的执行。本篇将重点介绍如何在Web环境中集成并使用Quartz,以及相关的...

    Quartz.Net任务调度

    Quartz.Net的设计灵感来源于Java的Quartz库,它允许开发者灵活地定义和管理作业(Jobs)以及触发器(Triggers),实现任务的自动化执行。 1. **Quartz.Net基本概念** - **作业(Jobs)**:作业是实际需要执行的...

    C#Quartz定时任务

    7. **监控与管理**:Quartz.NET提供了Web管理界面(如`DotNetScheduler`),可以实时查看和管理任务状态,也可以通过API接口进行远程控制。 通过上述知识,你不仅可以理解C# Quartz定时任务的基本原理,还能构建...

    Spring+Quartz实现任务调度的小例子

    Quartz提供了一个Web界面(JMX支持)用于监控和管理任务,但这个例子中没有包含这部分。如果需要,可以集成Quartz的AdminServlet或使用其他方式监控任务状态。 综上所述,Spring与Quartz的结合使用能够轻松实现复杂...

    Springboot2-Quartz 后台可动态配置的定时任务

    本项目“Springboot2-Quartz 后台可动态配置的定时任务”是基于SpringBoot 2.x版本与Quartz Scheduler整合的一个示例,它展示了如何在后台管理系统中动态地创建、更新和删除定时任务,以及监控这些任务的状态,为...

    springMVC+quartz任务调度

    在实际项目中,SpringMVC 和 Quartz 的结合可以帮助开发者构建出高效、灵活的应用程序,尤其是对于那些需要定期执行后台任务的系统,如数据分析、监控报警等。同时,由于 Spring 提供了对 Quartz 的良好支持,使得...

    quartZ定时任务.zip

    下面将详细介绍如何利用Quartz在SpringBoot项目中创建、管理和停止定时任务,并根据业务需求配置cron表达式来设定执行周期。 1. **Quartz简介** - Quartz是Java平台上的一个强大、灵活的作业调度库,它可以与Java...

    quartz 定时任务调度

    Quartz是中国著名的开源作业调度框架,它为Java应用程序提供了完全的定时任务管理功能。Quartz的核心在于其强大的调度引擎,可以灵活地安排和执行各种任务。在“quartz 定时任务调度”这个主题中,我们将深入探讨...

Global site tag (gtag.js) - Google Analytics