Spring Batch查找开始的工作执行

时间:2019-07-11 09:44:51

标签: java spring spring-batch

我有一份工作的Spring Batch应用程序。作业执行顺序对我来说至关重要,因此将JobLauncher配置为单线程作业池。换句话说,如果触发了很少的执行,则一个执行将在运行,而其他执行将在队列中等待。

工作执行表将如下所示:

        ╒═════╤═════════════════════╤════════════╤════════════╤═════╕
        │ ... │ START_TIME          │ END_TIME   │ STATUS     │ ... │
        ╞═════╪═════════════════════╪════════════╪════════════╪═════╡
        │ ... │ 2019-07-11 11:03:08 │ NULL       │ STARTED    │ ... │
        ├─────┼─────────────────────┼────────────┼────────────┼─────┤
        │ ... │ NULL                │ NULL       │ STARTING   │ ... │
        └─────┴─────────────────────┴────────────┴────────────┴─────┘

如果JVM崩溃,我需要从该状态恢复并进行一些审核,因此我需要查找所有STARTEDSTARTING执行。

找到第一个不是问题,我可以用JobExplorer来做到:

Set<JobExecution> executions = jobExplorer.findRunningJobExecutions("jobName");

它只会给我STARTED的当前START_TIME处决权。但是如何找到所有STARTING行刑?

到目前为止,我发现的唯一方法是遍历作业实例,然后为每个实例找到STARTING执行。像这样:

        jobExplorer.findJobInstancesByJobName("jobName", 0, 100)
                .forEach(jobInstance -> {
                    jobExplorer.getJobExecutions(jobInstance)
                            .stream()
                            .filter(execution -> STARTING.equals(execution.getStatus()))
                            .forEach(execution -> {
                                // do the job
                            });
                });

这里的问题是,您始终进行有限制的完全扫描(我指定为100)。在Spring Batch中,有没有像jobExplorer.findStartingJobExecutions("jobName")这样的更好方法?

1 个答案:

答案 0 :(得分:0)

我看不到任何公共API可以按状态获得作业执行。您可以做的是(使用伪代码):

JobInstance jobInstance = jobInstanceDao.getJobInstance(jobName, jobParameters);
List<JobExecution> jobExecutions =  jobExplorer.findJobExecutions(jobInstance);
// iterate over job execution and filter by status

这将避免加载所有作业实例(一次加载100个)。

也就是说,我认为JobRepository接口可以添加一种通过名称和参数(类似于isJobInstanceExists)来获取作业实例的方法,以避免使用jobInstanceDao之前的代码段。

编辑:

我想您的最初要求是将作业执行标记为无法重新启动。为此,您可以手动将作业执行的状态(及其步骤执行)更改为FAILED并将其END_TIME设置为非null值(此处说明:https://docs.spring.io/spring-batch/4.1.x/reference/html/job.html#aborting-a-job )。这样,您将能够重新启动失败的执行。