views:

167

answers:

1

In my Spring application I'm using the SchedulerFactoryBean to integrate with Quartz. We're going to have clustered Tomcat instances, and thus I want to have a clustered Quartz environment, so that the same jobs don't run at the same time on different web servers.

To do this, my app-context.xml is as follows:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="cronTrigger"/>
            <ref bean="simpleTrigger" />
        </list>
    </property>
    <property name="dataSource" ref="dataSource"/>
    <property name="overwriteExistingJobs" value="true"/>
    <!-- found in applicationContext-data.xml -->
    <property name="applicationContextSchedulerContextKey" value="applicationContext"/>
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceName">SomeBatchScheduler</prop>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
            <!--<prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>-->
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">25</prop>
            <prop key="org.quartz.threadPool.threadPriority">5</prop>
        </props>
    </property>
</bean>

Everything works well, except that when I attempt to remove or change a trigger, then restart my app, the old triggers are still persisted in the DB, and still run. I don't want this, I just want them to be deleted when the app stops (or is restarted). I set the value of the overwriteExistingJobs property to be true, since I thought that's what it did.

Any ideas? All I want to use the DB for is clustering, not any sort of persistence beyond that.

+1  A: 

I have done research on the topic and that's a well-known bug in Quartz, I found a few posts on their forum. To solve this problem I created a bean that deletes all the records in the Quartz table. You can call this bean before your Quartz bean is loaded (add a "depends-on" on your Scheduler bean), when your spring context is being destroyed (make sure the DB connection pool is still opened), or manually through some form of UI. There's also a bug on job groups, don't be surprised. My first fix was to create a customer Quartz jar with the fix but it got pretty hard to upgrade whenever they released a new version (I was using 1.4 or 1.5 at the time - don't really remember).

Felipe Oliveira