首页 文章

使用jobparameters重新启动Spring批处理

提问于
浏览
0

是否可以在Spring批处理中为特定参数重新启动作业?

我在元表中有两个失败的作业实例 . 每个作业都有自己的作业参数 . 现在,我想用给定的参数重新启动作业 . 即使我传递了job参数,它也总是只重新启动最后一次失败的执行 .

我的工作:

<batch:job id="JobA"  incrementer="runIdIncrementer">
    <batch:step id="abcde">
        <batch:tasklet transaction-manager="transactionManager">
            <batch:chunk reader="Reader" writer="Writer" processor="Processor" commit-interval="100" />
        </batch:tasklet>
    </batch:step>
</batch:job>

我将在两个不同的实例中使用不同的参数启动JobA . 假设JobA为1234帐户,JobA为5678帐户 . 两个实例都失败了 . 现在我想重新启动JobA for 1234帐户 . 但无论参数如何,Spring批次总是重新启动最后一次失败的操作 .

Edited 调试 CommandLineJobRunner 我发现此代码总是重新启动最新的失败作业,而不管作业参数如何:

private JobExecution getLastFailedJobExecution(String jobIdentifier) {
    List<JobExecution> jobExecutions = getJobExecutionsWithStatusGreaterThan(jobIdentifier, BatchStatus.STOPPING);
    if (jobExecutions.isEmpty()) {
        return null;
    }
    return jobExecutions.get(0);
}

2 回答

  • 0

    我们遇到了同样的问题,对我而言,这看起来像是一个缺陷,特别是在比较SimpleJobLauncher如何评估上一个工作时 .

    如您所述,getLasFailedJobExecution()不会考虑参数 . (至少在我看来,这是错误的 . 你可以使用不同的识别参数运行相同的工作,但只有其中一个运行失败才能重新启动 . )

    另一方面,SimpleJobLauncher根据参数获取最后的作业执行:

    public JobExecution run(final Job job, final JobParameters jobParameters)
            throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException,
            JobParametersInvalidException {
    ...
    
        JobExecution lastExecution = jobRepository.getLastJobExecution(job.getName(), jobParameters);
    ...
    

    这不一致 .

    我们修复它的方法是实现我们自己的CommandLineJobRunner,它来自CommandLineJobRunner,但你必须覆盖整个start方法,因此,你必须复制几个私有方法 .

    start方法中的整个重启部分必须改变如下:

    if (opts.contains("-restart")) {
                JobExecution lastExecution = jobRepository.getLastJobExecution(job.getName(), jobParameters);
    
                if (!jobExecution.getStatus().isGreaterThan(BatchStatus.STOPPING)) {
                    throw new JobExecutionNotFailedException("No failed or stopped execution found for job="
                            + jobIdentifier);
                }
                jobParameters = jobExecution.getJobParameters();
                jobName = jobExecution.getJobInstance().getJobName();
            }
    

    Edited

    有时我真的应该阅读javadoc ......

    如果重新启动,您可以传递executionid而不是jobname . 在这种情况下,它将找到正确的重新执行 .

    从主方法的javadoch:

    restart :(可选)如果作业失败或停止,则应重新启动 . 如果指定,则jobIdentifier参数可以解释为作业的名称或失败的作业执行的ID .

    因此,在重新启动的情况下使用执行ID将确保重新启动正确的实例 . 在这种情况下,您也不必提供任何其他参数,因为它们将从上次执行中获取 .

  • 2

    如果您将 same set of parameters 第二次传递给CommandLineJobRunner,则作业将在失败时重新启动 .

    选项'-restart'是为重新启动某些类型的运行而提供的额外快捷方式(例如,上次失败的运行)

相关问题