【问题标题】:Restart a spring batch job重新启动春季批处理作业
【发布时间】:2020-11-19 23:05:09
【问题描述】:

我有一个 spring 批处理作业,它从 CSV 文件读取并写入数据库。我想让它重新启动。例如,如果在读取文件或写入数据库时​​出现异常导致作业失败,它应该从失败的相同点/块重新开始,而不仅仅是从头开始读取整个文件。

我正在从端点触发作业启动器,并已在我的控制器中对其进行了配置。

目前我正在通过控制器将参数jobId(这是一个唯一标识符/编号)传递给作业参数以运行新的作业实例。如果作业失败,我会使用与 GET 请求中的参数相同的 jobId 再次触发它,它会按预期从该作业 ID 上次失败的位置重新启动作业。 这种方法的问题是我必须手动维护一个单独的 jobId 参数列表。即使我必须运行一个新的作业实例,我也不想提供我自己的 jobId 参数。此外,如果我没有在 GET 请求中为 jobId 参数传递任何值,此方法将失败,因此也无法重新启动该作业实例。

我期待是否有一种方法可以触发端点,而无需为每个新的作业实例使用我自己的任何参数,如果作业失败,我想使用 JOB_EXECUTION_IDJOB_INSTANCE_ID 重新启动它形成 Spring Batch 元数据表。

控制器:

@Autowired
JobLauncher jobLauncher;

@Autowired
Job demoJob;

@GetMapping("/demo")
public BatchStatus runDemoJob(@RequestParam(name = "jobId", required = false) String jobId) 
throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException 
{
        JobParameters p = new JobParameters();

        if (!jobId.isEmpty()) {
            p = new JobParametersBuilder().addString("jobId", jobId).toJobParameters();
        }

        JobExecution j = jobLauncher.run(demoJob, p);

        return j.getStatus();

    }
}

【问题讨论】:

  • 为什么不使用 csv 文件名作为作业参数?如果文件名是唯一的,则每个文件都有一个作业实例,并且您可以在失败的情况下重新启动它。
  • @MahmoudBenHassine 我必须一次又一次地读取同一个文件,因为其中的数据会发生变化。因此,在我的情况下,不可能使用文件名作为参数。我需要一些独特的东西,比如 executionIdinstanceId

标签: java spring spring-boot spring-batch


【解决方案1】:

我必须一次又一次地读取同一个文件,因为其中的数据会发生变化

批处理是关于固定数据集的。内容不断变化的单个文件不是固定的数据集。流式解决方案可能更适合您的用例。一个 spring 批处理作业实例应该代表一个固定的数据集(通过识别作业参数来识别)。这对于可重启性至关重要。

【讨论】:

  • 我的意思是内容可能会在一次执行完成后、下一次执行开始之前发生变化。我通过将时间戳作为作业参数而不是自创建的 jobId 来解决了可重启性问题。
  • 这并不意味着您解决了可重启性问题。使用这种方法,您无法确定重新启动先前失败的作业实例是否会处理相同的数据,因为文件内容可能在此期间已更改。重新启动失败的作业实例应该真正重播由该作业实例表示的完全相同的数据集(即确切的文件、数据库表中的相同记录等)。
猜你喜欢
  • 2020-04-23
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多