论坛首页 Java企业应用论坛

Quartz任务监控管理 (1)

浏览 73343 次
该帖已经被评为精华帖
作者 正文
   发表时间: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就足够了。
0 请登录后投票
   发表时间: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]
0 请登录后投票
   发表时间: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删除后再试试。
0 请登录后投票
   发表时间:2009-09-21  
有个问题想问一下,如果当任务执行的时间点上,正好服务器down掉或由于其他原因任务没有顺利完成
该如何自动或手动唤醒它,让他顺利执行呢?

  • 大小: 13.1 KB
0 请登录后投票
   发表时间: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执行
0 请登录后投票
   发表时间: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帮忙解决一下咯!非常感谢!
0 请登录后投票
   发表时间: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好象不能人工控制,这个我也不太清楚。

0 请登录后投票
   发表时间: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能有什么好的建议?
0 请登录后投票
   发表时间:2009-09-30  
LZ:我发现spring的事务与实现序列化有冲突,当我把实现序列化的service加上事务时,启动tomcat老报什么不能类型转换的错误,去掉序列化就不出问题了,但是,这样我的job所依赖的service启不是不能用了?能有好的方法:
即可以加事务,又不影响quartz的任务执行?包括使用hibernateTempalte。
0 请登录后投票
   发表时间: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启动后就自动执行了。这样不知道会出问题不?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics