先说一下业务需求:
我现在在公司经理安排了一个任务,要求把几张表要生成的报表数据,插入到一张新表里面,然后到时候用户直接查这张新表,但是这个操作是需要系统自动运行的,也就是不需要人工干预,而且是分“每年” ,“每半年”,“每季度”,“每月”,“每旬”,“每周(一年里面的周,不是一个月里面的)”这6种阶段来获取数据,比如每到一年的12.31号要进行“年”、“半年”、“月”、“旬”、“周”(如果12.31号是星期天)数据统计出来并且插入到新表里面。这就是大概业务需求的一个概述。
技术实现:
         1:第三方jar包:quartz包和spring.
2:把生成的报表插入到数据库里面我用的是 “insert into table select” 语句.
3:数据库是sql server 2000.
4:DAO使用技术,纯jdbc.

我的问题详细描述:
  1:第一个什么时候开始来生成报表,我想用每个临界点(也就是比如“年”的最后一天的最后一秒 2010-12-31:23:59:59,如果“半年”可能是2010-06-30 12:59:59、也可能是2010-12-31 12:59:59)的时候来开始执行任务。结果我这样肯定不对,因为我刚才上面说了。12.31号就要执行最少4个任务,但是发现有些任务他根本就没有执行,这个我就不知道什么意思咯。。我不知道quartz的对这个任务储存机制是怎么的?我想应该是用一个队列实现的吧,但是如果用队列实现,应该就算我的操作数据库的时间过程,产生线程阻塞,其他的任务也应该会执行啊,当然这里也有可能多个任务都是往一个表里面插数据,数据库对表锁定。但是不管怎么说,我认为任务肯定会执行,只是一个时间问题,但是让我失望的是没有执行,我把操作数据库的代码注释掉,每个任务里面写上了System.out.print();语句,结果居然一个任务都没执行,但是有时候有鬼使神差的执行了,郁闷中,但是我发现个问题,比如我的任务是写在23:59:59秒执行,有的是 第二天的00:00:05去了,当然我知道线程这种东西本来就是要看很多原因的,所以我觉得执行时间应该早一点,但是希望大家帮我想一个万全之策。
  2:第二个问题,如果今天(也就是2010-03-02)到星期6(也就是2010-03-06)录了一些数据进去,但是因为这几天是不 会执行这个自动插入功能的,因为这几天都不在上面的6个执行任务(年,半年,季度...)的条件里面,但是整好是星期6晚上把tomcat关闭了,,然后等到下个月再来启动,那么这5天的数据就会丢失掉了。当然我有个解决办法就是,拿出最后一次插入表的日期,然后再tomcat启动的时候再自己写一个监听器跟随其启动,然后把没有的数据给补上。但是这样工作量是比较大的。

问题简要概括:
    综合上面的“问题详细描述”,我写出了以下3个我想要问的问题
1:为什么有时候quartz到时间了不执行.
2:怎么控制其执行的时间最为恰当,我想在23:59:59不恰当。
3:因为这个涉及到多线程的问题,可能由于种种原因,导致有些时间的数据不能插入到新表中,出现数据不完整,比如上面的第一个,quartz不执行的情况就会导致这样的问题。
4:当tomcat关闭的时候,下次再启动,如何来判断关闭前的最后一次统计。
以上问题我有一些实现方法,再详细描述里面也有提及,但是感觉太麻烦,希望高手帮我一下,大家讨论一下。

我的代码:
    1:JAVA
         /**
 * 年处理
 * 
 * @throws Exception
 */
public void yearTarget() throws Exception {
System.out.println(simpleDateFormat.format(new Date()));
System.err.println("---------------进年处理");
}
/**
 * 半年处理
 */
public void yearHalfTarget() {
System.out.println(simpleDateFormat.format(new Date()));
System.err.println("---------------进半年处理");
} /**
 * 季度处理
 */
public void quarterTarget() {
System.out.println(simpleDateFormat.format(new Date()));
System.err.println("---------------进季度处理");
} /**
 * 月处理
 */
public void monthTarget() {
System.out.println(simpleDateFormat.format(new Date()));
System.err.println("---------------进月处理");
} /**
 * 旬处理
 */
public void xunTarget() {
System.out.println(simpleDateFormat.format(new Date()));
System.err.println("---------------进旬处理");
} /**
 * 周处理
 */
public void weekTarget() {
System.out.println(simpleDateFormat.format(new Date()));
System.err.println("---------------进周处理");
}
2.quartz配置,spring里面配的。
     <!-- ******************定义JobDetail*********************  -->
<bean id="targetService"
class="com.jwx.dcim.sars.query.action.TargetService" />
<!-- 年 -->
<bean id="yearJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="targetService" />
<property name="targetMethod" value="yearTarget" />
<property name="concurrent" value="false" />
</bean>
<!-- 半年 -->
<bean id="yearHalfJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="targetService" />
<property name="targetMethod" value="yearHalfTarget" />
<property name="concurrent" value="false" />
</bean>
<!-- 季度 -->
<bean id="quarterJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="targetService" />
<property name="targetMethod" value="quarterTarget" />
<property name="concurrent" value="false" />
</bean>
<!-- 月 -->
<bean id="monthJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="targetService" />
<property name="targetMethod" value="monthTarget" />
<property name="concurrent" value="false" />
</bean>
<!-- 旬 -->
<bean id="xunJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="targetService" />
<property name="targetMethod" value="xunTarget" />
<property name="concurrent" value="false" />
</bean>
<!-- 周 -->
<bean id="weekJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="targetService" />
<property name="targetMethod" value="weekTarget" />
<property name="concurrent" value="false" />
</bean>
<!-- ******************定义Trigger 格式:秒,分,时,日期(?),月份,星期(?),年(可选)************* -->
<!-- 每年  -->
<bean id="yearTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="yearJob" />
<property name="cronExpression" value="10 59 23 31 12 ?" />
</bean> <!-- 上半年,下半年  -->
<bean id="yearHalfTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="yearHalfJob" />
<property name="cronExpression" value="20 59 23 L 6,12 ?" />
</bean> <!-- 季度  -->
<bean id="quarterTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="quarterJob" />
<property name="cronExpression" value="30 59 23 L 5,8,11,2 ?" />
</bean>
<!-- 月  -->
<bean id="monthTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="monthJob" />
<property name="cronExpression" value="40 59 23 L * ?" />
</bean> <!-- 旬统计  -->
<bean id="xunTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="xunJob" />
<property name="cronExpression" value="50 59 23 1/10 * ?" />
</bean> <!-- 周统计  -->
<bean id="weekTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="weekJob" />
<property name="cronExpression" value="59 59 23 ? * 1" />
</bean>
 
<!-- ******************定义Scheduler*********************  -->
<bean id="schedule"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
 
<ref bean="yearTrigger" />
<ref bean="yearHalfTrigger" />
<ref bean="quarterTrigger" />
<ref bean="monthTrigger" />
<ref bean="xunTrigger" />
<ref bean="weekTrigger" />
</list>
</property>
<property name="autoStartup" value="true" />
</bean>最后谢谢大帮忙。。

解决方案 »

  1.   

    重新把上面的问题写一下,因为上面的格式出现了问题我的问题详细描述:1:第一个什么时候开始来生成报表,我想用每个临界点(也就是比如“年”的最后一天的最后一秒 2010-12-31:23:59:59,如果“半年”可能是2010-06-30 12:59:59、也可能是2010-12-31 12:59:59)的时候来开始执行任务。结果我这样肯定不对,因为我刚才上面说了。12.31号就要执行最少4个任务,但是发现有些任务他根本就没有执行,这个我就不知道什么意思咯。。我不知道quartz的对这个任务储存机制是怎么的?我想应该是用一个队列实现的吧,但是如果用队列实现,应该就算我的操作数据库的时间过程,产生线程阻塞,其他的任务也应该会执行啊,当然这里也有可能多个任务都是往一个表里面插数据,数据库对表锁定。但是不管怎么说,我认为任务肯定会执行,只是一个时间问题,但是让我失望的是没有执行,我把操作数据库的代码注释掉,每个任务里面写上了System.out.print();语句,结果居然一个任务都没执行,但是有时候有鬼使神差的执行了,郁闷中,但是我发现个问题,比如我的任务是写在23:59:59秒执行,有的是 第二天的00:00:05去了,当然我知道线程这种东西本来就是要看很多原因的,所以我觉得执行时间应该早一点,但是希望大家帮我想一个万全之策。 2:第二个问题,如果今天(也就是2010-03-02)到星期6(也就是2010-03-06)录了一些数据进去,但是因为这几天是不 会执行这个自动插入功能的,因为这几天都不在上面的6个执行任务(年,半年,季度...)的条件里面,但是整好是星期6晚上把tomcat关闭了,,然后等到下个月再来启动,那么这5天的数据就会丢失掉了。当然我有个解决办法就是,拿出最后一次插入表的日期,然后再tomcat启动的时候再自己写一个监听器跟随其启动,然后把没有的数据给补上。但是这样工作量是比较大的。问题简要概括:综合上面的“问题详细描述”,我写出了以下3个我想要问的问题 1:为什么有时候quartz到时间了不执行. 2:怎么控制其执行的时间最为恰当,我想在23:59:59不恰当。 3:因为这个涉及到多线程的问题,可能由于种种原因,导致有些时间的数据不能插入到新表中,出现数据不完整,比如上面的第一个,quartz不执行的情况就会导致这样的问题。 4:当tomcat关闭的时候,下次再启动,如何来判断关闭前的最后一次统计。
    以上问题我有一些实现方法,再详细描述里面也有提及,但是感觉太麻烦,希望高手帮我一下,大家讨论一下。
      

  2.   

    好长啊,没有看全,
    楼主想实现定时任务吧,用spring完全可以实现,会用就可以,不麻烦。
    1.配好定时
    2.写好你的任务方法体,无参方法定时配置给个例子供参考 <bean id="sfb" 
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
      <property name="triggers">
        <list>
    <ref local="treeBussJobTrigger"/>
        </list>
      </property>
    </bean>
    <!-- 触发方法配置 -->   
    <bean id="treeBussJob" 
      class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="相应类" />
        <property name="targetMethod" value="相应方法" />
    </bean>
    <!-- 触发时间配置 -->
    <bean id="treeBussJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
      <property name="jobDetail" ref="treeBussJob" />
      <property name="cronExpression" value="0 0/5 * * * ?" />
    </bean>
    <!-- TreeBuss定时更新end -->
      

  3.   

    “当使用''L''选项时,指定确定的列表或者范围非常重要,否则你会被结果搞糊涂的。”
    这个是网上查的 
    建议LZ先把L改成具体的时间测试一下 看看是不是L选项的问题
    以前用过quartz 但是 没用的这么复杂