【问题标题】:Spring Batch find starting job executionsSpring Batch 查找开始作业执行
【发布时间】:2019-11-21 00:05:11
【问题描述】:

我有一个带有一份工作的 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") 这样更好的方法?

【问题讨论】:

    标签: java spring spring-batch


    【解决方案1】:

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

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

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

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

    编辑:

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

    【讨论】:

    • 感谢您的回答,但我在申请开始时没有jobParameters。我可以以某种方式只为STARTING 工作获得它们吗?可能有很多。
    • 不使用提供的 API,但您可以随时使用 jdbcTemplate 自己进行操作。我编辑了答案,详细说明了如何重新启动作业执行。
    • 感谢您的回复,但对我来说主要问题是找到状态为STARTING 的作业执行,并且我可以有多个具有此类作业执行的作业实例。我不想为此编写自己的 JDBC 查询,然后再支持它。所以我正在寻找一些使用 Batch API 的方法。
    • 正如我所提到的,批处理 API 不提供按状态获取作业执行的方法。但我要问你:为什么你首先需要以STARTING 状态执行工作?我想我们在这里面临XY problem,我正在努力帮助您解决您的实际问题。
    • 感谢您的努力。我在问题中提到我的问题是在 JVM 崩溃后恢复和审核我的作业执行队列。我发布了我找到的解决方案,它有效。但是发布的解决方案更像是一种解决方法,我正在寻找更好的解决方案。但我看不出你对jobInstanceDao 的建议对我有什么帮助。
    猜你喜欢
    • 2014-12-10
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 2012-06-12
    • 1970-01-01
    相关资源
    最近更新 更多