嗨春批用户,
关于文档http://docs.spring.io/spring-batch/reference/htmlsingle/#d5e1320
"如果进程死亡(" kill -9"或服务器故障),当然,作业没有运行,但JobRepository无法知道,因为没有人告诉它在这个过程死亡之前。"
我尝试使用
查找并重新启动过时的作业执行Set<JobExecution> jobExecutions = jobExplorer.findRunningJobExecutions(jobName);
...
jobExecution.setStatus(FAILED);
jobExecution.setEndTime(new Date());
jobRepository.update(jobExecution);
jobOperator.restart(jobExecution.getId());
但这似乎非常不方便。 1)我必须在其他(新)工作开始之前这样做。 2)我必须处理运行服务器的多个实例,因此findRunningJobExecutions不会起作用。
您可以找到有关此主题的其他问题: https://jira.spring.io/browse/BATCH-2433?jql=project%20%3D%20BATCH%20AND%20status%20%3D%20Open%20ORDER%20BY%20priority%20DESC Spring Batch after JVM crash
我希望看到一个解决方案来注册&#34;启动干净的工作听众&#34;。这仍然无法解决多服务器环境引起的问题,因为Spring批处理不知道STARTED标记的JobExecution是否未在另一个实例上运行。
感谢您的任何建议 亚历克斯
答案 0 :(得分:0)
您的工作不能也不应该从kill -9
方案中“自动”恢复。 kill -9
的处理方式与投掷被捕Exception
的应用程序的处理方式大不相同。这样做的原因是您已经有效地从应用程序中取出地毯,而没有给它机会与数据库达到同步点以向ExecutionContext
提交任何必要信息或更新作业/步骤状态(ES)。因此,数据库的最后一个状态接触点将保留,作业仍将显示STARTED
。
“好吧,很好”,你说,“但如果我开始另一次执行,我希望它找到STARTED
执行,并从它停止的地方继续。”这里的问题是,应用程序没有干净的方法来区分正在运行的作业与已失败但无法启动数据库的作业。这里的框架在谨慎方面正确地犯了错误并阻止您启动已经运行的作业,这是一件好事。
为什么呢?因为我们假设您的工作实际上仍在运行,并且您意外重新启动。编码后,框架将开始旋转,查看正在运行的执行并失败并显示以下消息A job execution for this job is already running
。我不能告诉你,有多少次我们被拯救了,因为有人不小心发了两次工作!
如果你要实现你建议的监听器,那么第二次执行将被允许启动,你将有两个不同的JVM重复相同的工作,可能写入相同的文件/表并导致巨大的数据混乱,可能无法清理。
相信我,如果Linux终端因为与数据库的连接被切断而终止你的工作或你的工作死亡,那么在尝试重启之前,你需要注意那些执行状态。
最后,如果你真的想要杀死你的工作,你可以利用其他几种标准模式来停止工作: