锁定老帖子 主题:Quartz任务监控管理 (1)
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间: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就足够了。 |
|
返回顶楼 | |
发表时间: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] |
|
返回顶楼 | |
发表时间:2009-09-17
最后修改:2009-09-21
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删除后再试试。 |
|
返回顶楼 | |
发表时间:2009-09-21
有个问题想问一下,如果当任务执行的时间点上,正好服务器down掉或由于其他原因任务没有顺利完成
该如何自动或手动唤醒它,让他顺利执行呢? |
|
返回顶楼 | |
发表时间:2009-09-21
最后修改: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执行 |
|
返回顶楼 | |
发表时间: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&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帮忙解决一下咯!非常感谢! |
|
返回顶楼 | |
发表时间: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好象不能人工控制,这个我也不太清楚。 |
|
返回顶楼 | |
发表时间:2009-09-30
/** * 初始化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 { int state = scheduler.getTriggerState("MYTRIGGER", "DEFAULT"); if(state==-1){ schedule("MYTRIGGER", "0/30 * 9-18 ? * MON-FRI *"); }else if(state==3){ boolean removeTrigger =removeTrigdger("MYTRIGGER", "DEFAULT"); boolean removeJob = scheduler.deleteJob("jobDetail", "DEFAULT"); if(removeTrigger && removeTrigger){ scheduler.addJob(jobDetail, true); schedule("MYTRIGGER", "0/30 * 9-18 ? * MON-FRI *"); } } } catch (SchedulerException e) { log.error("the schedulerService.getScheduler().getTriggerState() is error!"+e.getMessage()); } System.out.println("Job init end......"); } 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能有什么好的建议? |
|
返回顶楼 | |
发表时间:2009-09-30
LZ:我发现spring的事务与实现序列化有冲突,当我把实现序列化的service加上事务时,启动tomcat老报什么不能类型转换的错误,去掉序列化就不出问题了,但是,这样我的job所依赖的service启不是不能用了?能有好的方法:
即可以加事务,又不影响quartz的任务执行?包括使用hibernateTempalte。 |
|
返回顶楼 | |
发表时间: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启动后就自动执行了。这样不知道会出问题不? |
|
返回顶楼 | |