首页 > 解决方案 > 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执行 present 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)。jobExplorer.findStartingJobExecutions("jobName")有没有像Spring Batch那样更好的方法?

标签: javaspringspring-batch

解决方案


我看不到公共 API 可以按状态执行作业。你可以做的是(在伪代码中):

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

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

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

编辑:

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


推荐阅读