Quartz 调度任务并发问题
假设 A任务没3秒执行一次,但执行周期为10秒,就会出现多个任务同时在跑的现象,如果只是查询不进行更新操作的话这个问题不大,但是如果有更新操作就会导致数据并发异常
以下是具体的测试案例:
定义一个任务类:
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date())+"开始");
try {
Thread.sleep(5 * 1000);
System.out.println(sdf.format(new Date())+"结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
定义一个触发器:
@Configuration
public class QuartzConfig {
private static String JOB_GROUP_NAME = "PJB_JOBGROUP_NAME";
private static String TRIGGER_GROUP_NAME = "PJB_TRIGGERGROUP_NAME";
/**
* 更新同步日志触发器
* @return
*/
@Bean
public Trigger updateCalendarJobTrigger()
{
CronTrigger trigger = TriggerBuilder
.newTrigger()
.forJob(updateCalendarJobDetail())
.withIdentity("updateCalendarJobTrigger", TRIGGER_GROUP_NAME)
.withSchedule(CronScheduleBuilder.cronSchedule("*/1 * * * * ?"))
.build();
return trigger;
}
@Bean
public JobDetail updateCalendarJobDetail()
{
JobDetail jobDetail = JobBuilder.newJob(TestJob.class)
.withIdentity("updateCalendarJobDetail",JOB_GROUP_NAME)
.storeDurably() //即使没有Trigger关联时,也不需要删除该JobDetail
.build();
return jobDetail;
}
}
执行结果如下:
2021-02-19 17:25:20开始
2021-02-19 17:25:21开始
2021-02-19 17:25:22开始
2021-02-19 17:25:23开始
2021-02-19 17:25:24开始
2021-02-19 17:25:25开始
2021-02-19 17:25:25结束
2021-02-19 17:25:26开始
2021-02-19 17:25:26结束
2021-02-19 17:25:27开始
2021-02-19 17:25:27结束
2021-02-19 17:25:28结束
2021-02-19 17:25:28开始
在任务类上添加
@DisallowConcurrentExecution
注解
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.text.SimpleDateFormat;
import java.util.Date;
@DisallowConcurrentExecution
public class TestJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date())+"开始");
try {
Thread.sleep(5 * 1000);
System.out.println(sdf.format(new Date())+"结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果如下:
2021-02-19 17:26:50开始
2021-02-19 17:26:55结束
2021-02-19 17:26:55开始
2021-02-19 17:27:00结束
2021-02-19 17:27:00开始
2021-02-19 17:27:05结束
2021-02-19 17:27:05开始
到此并发问题解决