【问题标题】:Unable to restart a Spring batch job无法重新启动 Spring 批处理作业
【发布时间】:2016-08-03 13:27:57
【问题描述】:

我有一个春季批处理作业,它读取、转换和写入 Oracle 数据库。我正在通过 CommandLineJobRunner 实用程序运行作业(使用由 maven shade 插件生成的 fat jar + 依赖项);由于“已达到 Java 堆内存限制”,该作业随后中途失败,并且该作业未标记为 FAILED,但仍显示状态 STARTED。

我尝试使用相同的作业参数(如文档建议的那样)重新运行作业,但这给了我这个错误:

5:24:34.147 [main] ERROR o.s.b.c.l.s.CommandLineJobRunner - Job Terminated in error: A job execution for this job is already running: JobInstance: id=1, version=0, Job=[maskTableJob]

org.springframework.batch.core.repository.JobExecutionAlreadyRunningException:此作业的作业执行已在运行:JobInstance:id=1,version=0,Job=[maskTableJob] 在 org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:120) ~[maskng-batch-1.0-SNAPSHOT-executable.jar:1.0-SNAPSH

我尝试了各种方法(例如使用 -restart 参数手动将状态设置为 FAILED),但均无济于事。有什么我在这里遗漏的,因为我认为春季批处理的优点之一是它能够重新开始他们停止的工作......!!?

【问题讨论】:

  • 重新运行作业不会使用相同的参数。添加当前时间作为参数重新运行。见mkyong.com/spring-batch/…。另请查看文档:docs.spring.io/spring-batch/reference/html/…
  • 是的,我知道,但是我需要重新运行一项特定的工作,因为我希望它能够从中断的地方继续。我的工作处理数 TB 的行,可能需要几天才能运行,所以我确实想每次都从头开始重新启动该死的东西 :-)
  • 我认为步骤中的块处理应该处理这些事情
  • 啊哈...我发现了问题!我已将 jobRepository 切换为使用另一个数据库,但这似乎给 Spring 造成了一些混乱,所以我放弃了所有内容并从头开始,现在可以按预期工作
  • @ChristopherRichardDobbs 阅读我的回答,如果您还需要其他内容,请告诉我。

标签: spring spring-batch


【解决方案1】:

您应该知道的第一件事是 Joblauncher 不能用于重新启动已经运行的作业。 您收到“JobExecutionAlreadyRunningException”的原因是因为您传递的参数已经存在于数据库中,因此您会收到此异常。

在 spring batch 中,如果 job 以“FAILED”状态或“STOPPED”状态完成,则可以重新启动。

JobOperator 具有重新启动方法,可用于通过传递以“FAILED”状态或“STOPPED”状态完成的作业执行 ID 来重新启动失败的作业。

请注意,如果作业以“已完成”状态完成,则无法重新启动该作业。 在这种情况下,您必须使用新的作业参数提交新作业

如果您想手动将作业的状态设置为失败,请运行以下查询并使用 JobOperator.restart() 方法重新启动作业。

update batch_job_execution set status="FAILED", version=version+1 where job_instance_id=jobId;

事务管理处理不当可能是您的工作状态未更新为“FAILED”状态的一种可能原因。即使作业遇到运行时异常,请确保您的事务正在完成。

【讨论】:

  • 非常感谢您的回复。我注意到,如果我有一个以 status=FAILED 和 exitstatus=UNKNOWN 完成的作业,我可以使用相同的作业参数重新运行该作业,但它似乎不会从中断的地方继续,而是开始一个全新的作业运行。这是使用 commandLineJobRunner,所以我将使用 java main 中的 jobOperator 进行调查,并按照您的说法手动设置退出状态!
  • 不客气,如果您认为我的回答已经解决了您的问题,请点击勾选标记接受它作为正确答案:)。
  • 我敲了一些 java 以通过 jobOperator 使用相同的作业参数重新启动作业,它似乎重新启动正常。我什至在日志中看到“恢复工作”,并认为一切正常......但是看起来我有一个新的执行 ID,并且工作步骤从头开始。我的目标数据库显示它包含比源更多的行,这证明它没有继续。
  • 另一个指标是我配置的 beforeJob() 监听器即使在作业重新启动时也会触发 - 这是正确的行为,因为我认为应该只在全新的作业上触发!??
  • 我真是个白痴……像往常一样使用 RTFM……我在我的 jdbcItemReader 中设置了 savestate=false……所以重启时脑死了 - 非常感谢您的 cmets它终于让我解决了这个问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
相关资源
最近更新 更多