How to skip a particular job execution in Spring Q

2019-08-01 23:57发布

问题:

I have a CronExpression set for the job to be executed at every 30 minutes. But I need to skip a particular job if the earlier job is not complete.

For eg. I have 100 Employee whose Names to be updated in the database and I terms it as "Job1" which starts at 10AM. Now the case is like "Job1" is in process and by the time I have another job- "Job2" aligned where I need to update another 50 Employee's names. My problem is this,I need to skip "Job2" and further jobs till my currently running Job is completed.

    <bean name="employeeNameUpdateJob" class="org.springframework.scheduling.quartz.JobDetailBean">
        <property name="name" value="Employee Update Job"/>
        <property name="group" value="Employee Update Group Job"/>
        <property name="jobClass"
            value="com.emp.scheduler.EmployeeUpdateScheduler" />
        <property name="volatility" value="false" />
    </bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="name" value="Employee Update Trigger"/>
        <property name="group" value="Employee Update Group Trigger"/>
        <property name="volatility" value="false" />
        <property name="jobDetail" ref="employeeNameUpdateJob"/>
        <property name="cronExpression" value="0 0/30 * * * ?"/>
    </bean>

回答1:

One way is to implement TriggerListener interface, which provides a vetoJobExecution(Trigger trigger, JobExecutionContext context) method to veto the execution of a next job. Returning true from this method will stop the execution of job.

Interface documentation: http://quartz-scheduler.org/api/2.0.0/org/quartz/TriggerListener.html#vetoJobExecution(org.quartz.Trigger, org.quartz.JobExecutionContext)

Sample:

//SampleTriggerListener.java
public class SampleTriggerListener implements TriggerListener {

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext ctx) {
        if(!previousJobCompleted)
            return true;

        return false;
    }
}


//Main.java
//init jobs, trigger & scheduler  
this.scheduler.addTriggerListener(new SampleTriggerListener());
this.scheduler.start();


回答2:

If they are the same job class : @DisallowConcurrentExecution

Else it sounds like you need to use a single threadpool executor. Inject the same executor to both classes ( or alternatively implement an orchestrator class to manage this ) and add the work units to the queue this way.



回答3:

If you will never need to run multiple jobs in parallel you could set the worker thread pool that Quartz uses to 1. Then it will only ever run one job at a time. In your quartz.properties file, set:

org.quartz.threadPool.threadCount: 1