我有一个弹簧批石英设置。我配置了两个并行运行的作业。作业正在读取文件,然后将一些数据写入数据库。这里是棘手的部分,文件名是在执行侦听器的beforeJob()方法中计算的。每个作业完成后,afterJob()将计算下一个fileName。文件名有以下模式xxxxxx.nnnn
where nn..是数字,有时序列可能有数字缺失,因此我试图"跳过"那些缺失的段落,当我找到一个现有的数字启动工作。
我想知道是否有可能限制每次cron触发器触发时启动的作业数量?我想有一个单一的工作启动后,一个计时触发器触发。
例如:
- 在下午12.30启动作业。
- 作业试图找到正确的文件
- 作业失败的FileNotFound(配置为不可跳过的异常)
- 作业完成后,fileName计数器增加
现在,当触发器触发时,我得到大约4个或更多相同类型的任务正在异步执行。在我的批处理设置中,我配置了两个<jobs>
,每个小时在彼此的5分钟间隔内一个接一个地启动。这两个作业都遵循示例中提供的流程。总而言之:是否有可能在cron触发器触发后启动单个作业,并使两个作业类型并行运行?
作业在执行之前应该知道要处理哪个文件。例如,文件名应该作为作业参数传递。删除JobExecutionListener
,添加StepExecutionListener
,通过StepExecution#getJobParameters()
访问作业参数。一个作业=一个文件
现在,从您的调度程序中,您希望确保在一个时间点只运行一个作业。您可以通过两种方式实现:
•使用异步任务执行器。在这种情况下,每次启动作业时,它都不会在后台执行(除非调度程序不是每次在新线程中触发定时器事件)。
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor" ref="taskExecutor" />
</bean>
<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
•如果您使用相同的作业启动器来执行其他需要在后台执行的作业,则需要使用ThreadPoolTaskExecutor
,但您可以手动检查作业是否正在运行:
for (final JobInstance jobInstance : jobExplorer.getJobInstances(jobName(), 0, LOOK_BEHIND_INSTANCES)) {
for (final JobExecution jobExecution : jobExplorer.getJobExecutions(jobInstance)) {
final BatchStatus status = jobExecution.getStatus();
if (status.isRunning()) {
// Ops:
break;
}
}
}