【发布时间】:2020-07-11 12:09:48
【问题描述】:
嘿,伙计们,我正在使用调度(使用 cron 触发器)进行春季批处理,它正在工作,但存在以下错误:
- 假设 cron 值每 10 秒启动一次批处理,当我启动第一个和之后,例如 3 秒,我启动另一个,spring 不会意识到 3 秒的间隙,它会启动它们就像我同时触发了它们一样
这是我的代码
这是我将要启动的工作的类别
@Component
public class JobThread implements Runnable {
@Autowired
private JobLauncher jobLauncher;
@Autowired
@Lazy
private Job job;
public JobParameters jobParameters;
private Logger log = Logger.getLogger(JobThread.class);
public synchronized void runBatch() {
jobParameters = new JobParametersBuilder().addLong("LaunchTime", System.currentTimeMillis())
.addString("TenantID", BatchController.getCurrentTenant().get()).toJobParameters();
try {
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
log.info("Job's Status:::" + jobExecution.getStatus());
} catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException
| JobParametersInvalidException e) {
e.printStackTrace();
}
}
@Override
public void run() {
this.runBatch();
}
}
将调用作业的控制器
@RestController
@RequestMapping("tenant/batch")
public class BatchController {
@Autowired
private ThreadPoolTaskScheduler taskScheduler;
@Autowired
@Qualifier("threadPoolTaskExecutor")
private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private JobThread jobThread;
private static ThreadLocal<String> currentTenant;
@PostMapping("/schedule")
public void setBatch(@RequestBody BatchBean cron) {
currentTenant = new ThreadLocal<String>() {
@Override
protected String initialValue() {
new TenantContext();
return TenantContext.getCurrentTenant();
}
};
//cron = "*/10 * * * * *";
taskScheduler.schedule(taskExecutor.createThread(jobThread), new CronTrigger(cron.getCron()));
}
我希望我已经足够清楚了 提前致谢
【问题讨论】:
-
您的代码有缺陷且危险。您将状态保持在单例中并覆盖该状态永远不要这样做。不要重新创建您的
ThreadLocal,也不要重新创建您的JobParamaters。只剩下最后一个。所以很危险。此外,您应该对接口而不是具体实现进行编程。不需要为可运行对象创建线程,因为您的JobThread已经是Runnable。
标签: spring spring-boot spring-integration spring-batch spring-scheduled