<div class="iteye-blog-content-contain" style="font-size: 14px">
最近正在做的项目,测试的时候发现定时调度任务会执行两次,于是乎查资料呀,都说是Tomcat配置问题,哥改了还是不行,后来无奈使用了一个网上说的方法,将JOB中的方法使用同步,通过一个静态变量进行控制,配置如下:
Xml代码
1. <bean id="sendOffMailTimerBean" class="com.c35.rouen.job.OffMailReportJob">
2. <property name="isolationAreaService">
3. <ref bean="isolationAreaService" />
4. </property>
5. </bean>
6.
7.<bean id="offMailReportJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
8. <property name="targetObject">
9. <ref bean="sendOffMailTimerBean"/>
10. </property>
11. <!-- 调用类中的方法 -->
12. <property name="targetMethod">
13. <value>doSend</value>
14. </property>
15. <property name="concurrent">
16. <value>false</value>
17. </property>
18. </bean>
19.
20. <bean id="deleteOffMailTimerBean" class="com.c35.rouen.job.OffMailDestroyJob">
21. <property name="isolationAreaService">
22. <ref bean="isolationAreaService" />
23. </property>
24. </bean>
25.
26.<bean id="offMailDestroyJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
27. <property name="targetObject">
28. <ref bean="deleteOffMailTimerBean"/>
29. </property>
30. <!-- 调用类中的方法 -->
31. <property name="targetMethod">
32. <value>doDelete</value>
33. </property>
34. <property name="concurrent">
35. <value>false</value>
36. </property>
37. </bean>
38.
39. <!-- 每天整点发送隔离邮件报告 -->
40.<bean id="offMailReportSendTrigger"
41. class="org.springframework.scheduling.quartz.CronTriggerBean">
42. <property name="jobDetail" ref="offMailReportJob"></property>
43. <property name="cronExpression">
44. <value>0 0 * * * ?</value>
45. </property>
46.</bean>
47.
48.<!-- 每天凌晨三点检查删除过期的隔离邮件 -->
49.<bean id="offMailDestroyTrigger"
50. class="org.springframework.scheduling.quartz.CronTriggerBean">
51. <property name="jobDetail" ref="offMailDestroyJob"></property>
52. <property name="cronExpression">
53. <value>0 0 3 * * ?</value>
54. </property>
55.</bean>
56.
57.<!-- 启动定时器 -->
58.<bean id ="schedulerFactory" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
59. <property name="triggers">
60. <list>
61. <ref bean="offMailReportSendTrigger" />
62. <ref bean="offMailDestroyTrigger" />
63. </list>
64. </property>
65.</bean>
<bean id="sendOffMailTimerBean" class="com.c35.rouen.job.OffMailReportJob">
<property name="isolationAreaService">
<ref bean="isolationAreaService" />
</property>
</bean>
<bean id="offMailReportJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="sendOffMailTimerBean"/>
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>doSend</value>
</property>
<property name="concurrent">
<value>false</value>
</property>
</bean>
<bean id="deleteOffMailTimerBean" class="com.c35.rouen.job.OffMailDestroyJob">
<property name="isolationAreaService">
<ref bean="isolationAreaService" />
</property>
</bean>
<bean id="offMailDestroyJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="deleteOffMailTimerBean"/>
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>doDelete</value>
</property>
<property name="concurrent">
<value>false</value>
</property>
</bean>
<!-- 每天整点发送隔离邮件报告 -->
<bean id="offMailReportSendTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="offMailReportJob"></property>
<property name="cronExpression">
<value>0 0 * * * ?</value>
</property>
</bean>
<!-- 每天凌晨三点检查删除过期的隔离邮件 -->
<bean id="offMailDestroyTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="offMailDestroyJob"></property>
<property name="cronExpression">
<value>0 0 3 * * ?</value>
</property>
</bean>
<!-- 启动定时器 -->
<bean id ="schedulerFactory" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="offMailReportSendTrigger" />
<ref bean="offMailDestroyTrigger" />
</list>
</property>
</bean>
JOB如下:
Java代码
1.public class OffMailReportJob extends QuartzJobBean {
2.
3. private IIsolationAreaService isolationAreaService;
4.
5. public IIsolationAreaService getIsolationAreaService() {
6. return isolationAreaService;
7. }
8.
9. public void setIsolationAreaService(IIsolationAreaService isolationAreaService) {
10. this.isolationAreaService = isolationAreaService;
11. }
12.
13. private static JLogger log = LoggerFactory.getLogger(OffMailReportJob.class);
14.
15. static int sendIndexFlag =0;//由doSend修改,其他方法不要修改此参数
16.
17. public void doSend() {
18.
19. // 定时器同时调用两次的问题需要查找原因
20. if (sendIndexFlag > 0)
21. return;// 保证同一时刻只有一个定时器运行,通过这种方式保证每次定时时间到时,只执行一个线程
22. sendIndexFlag = 1;// 锁定
23.
24. try {
25. isolationAreaService.sendOffMailReport();
26. } catch (Exception e) {
27. log.error(e.getMessage(), e);
28. }
29.
30. sendIndexFlag = 0;// 锁定解除
31. }
32.
33. @Override
34. protected void executeInternal(JobExecutionContext arg0)
35. throws JobExecutionException {
36. }
public class OffMailReportJob extends QuartzJobBean {
private IIsolationAreaService isolationAreaService;
public IIsolationAreaService getIsolationAreaService() {
return isolationAreaService;
}
public void setIsolationAreaService(IIsolationAreaService isolationAreaService) {
this.isolationAreaService = isolationAreaService;
}
private static JLogger log = LoggerFactory.getLogger(OffMailReportJob.class);
static int sendIndexFlag =0;//由doSend修改,其他方法不要修改此参数
public void doSend() {
// 定时器同时调用两次的问题需要查找原因
if (sendIndexFlag > 0)
return;// 保证同一时刻只有一个定时器运行,通过这种方式保证每次定时时间到时,只执行一个线程
sendIndexFlag = 1;// 锁定
try {
isolationAreaService.sendOffMailReport();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
sendIndexFlag = 0;// 锁定解除
}
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
}
照此修改时可以解决问题滴
后台又查啊查的,发现问题的根本:
web容器启动的时候,读取applicationContext.xml文件时,会加载一次。
第二次:Spring本身会加载applicationContext.xml一次。
一般来说,我们的quartz配置就是写在applicationContext.xml文件里的。
解决办法很简单
先把quartz配置信息提取出来,单独存成一个文件,比如applicationContext-quartz.xml
然后修改web.xml,让web容器启动时,可以加载该文件
这样quartz只会在web容器启动时加载一次,Spring不会再加载了。
COPY FROM :http://max-1106.iteye.com/blog/899055
</div>