Ice*_*nte 5 spring spring-batch
我正在尝试解决 Spring Batch 中最近困扰我们系统的问题。我们有一份工作,大部分工作都很好。这是一个多步骤的工作,下载和处理数据。
问题是有时工作会爆炸。也许我们尝试连接的服务器抛出错误,或者我们在工作中关闭了服务器。此时,下次我们的石英调度程序尝试运行该作业时,它似乎什么也没做。以下是此作业定义的简化版本:
<batch:job id="job.download-stuff" restartable="true">
<batch:validator ref="downloadValidator"/>
<batch:step id="job.download-stuff.download">
<batch:tasklet ref="salesChannelOrderDownloader" transaction-manager="transactionManager">
<batch:transaction-attributes isolation="READ_UNCOMMITTED" propagation="NOT_SUPPORTED"/>
<batch:listeners>
<batch:listener ref="downloadListener"/>
<batch:listener ref="loggingContextStepListener" />
</batch:listeners>
</batch:tasklet>
<batch:next on="CONTINUE" to="job.download-stuff.process-stuff.step" />
<batch:end on="*" />
</batch:step>
<batch:step id="job.download-stuff.process-stuff.step">
...
</batch:step>
<batch:listeners>
<batch:listener ref="loggingContextJobListener"/>
</batch:listeners>
Run Code Online (Sandbox Code Playgroud)
一旦进入这种状态,就会downloadValidator运行,但它永远不会进入第一步download-stuff.download。我在 tasklet 中设置了一个断点,但它永远不会进入。
如果我清除存储在我们的 mysql 数据库中的所有 spring 批处理表,并重新启动服务器,它将再次开始工作,但我宁愿了解是什么阻止它此时无法正常运行,而不是采用焦土策略使工作运行。
我是 Spring Batch 的新手,说得客气一点,所以如果我省略了重要的细节,请原谅我。我已经设置了断点并打开了日志记录以了解我所能做的。
到目前为止,我通过数据库观察到的条目似乎不再写入 BATCH_STEP_EXECUTION 和 BATCH_JOB_EXECUTION 表。
没有未处于 COMPLETED 状态的作业的 BATCH_JOB_EXECUTION 条目,也没有未处于 COMPLETED 状态的 BATCH_STEP_EXECUTION 条目
您会看到定义了一个 batch:validator,我已经确认 spring batch 调用该验证器并且它成功通过(设置断点并逐步通过)。第一步不执行。
loggingContextJobListener 和 loggingContextStepListener 似乎都没有触发。什么可能导致这种情况?
更新
我仔细查看了downloadListener作为批处理添加的:侦听器。这是 afterStep 的源代码:
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public ExitStatus afterStep(StepExecution stepExecution) {
long runSeconds = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - nanoStart);
// If Success - we're good
if (stepExecution.getStatus() == BatchStatus.COMPLETED) {
Long endTs = stepExecution.getExecutionContext().getLong("toTime");
Date toTime = new Date(endTs);
handleSuccess(toTime, stepExecution.getWriteCount());
return null;
}
// Otherwise - record errors
List<Throwable> failures = stepExecution.getFailureExceptions();
handleError(failures);
return ExitStatus.FAILED;
}
Run Code Online (Sandbox Code Playgroud)
我确认该return ExitStatus.FAILED行已执行并且抛出的异常记录在 failureExceptions 中。似乎一旦发生这种情况 BATCH_JOB_EXECUTION 条目处于 COMPLETED 状态(和 exit_code)并且 STEP_EXECUTION 失败。
此时,BATCH_JOB_EXECUTION_PARAMS 表中的条目仍然存在。我实际上尝试修改它们的 KEY_NAME 和 value 列的值,但这仍然不允许作业运行。只要有参数绑定到 JOB_EXECUTION_ID,属于同一个 BATCH_JOB_INSTANCE 的另一个作业就不能运行。
一旦我删除条目BATCH_JOB_EXECUTION_PARAMS该特定JOB_EXECUTION_ID,另一BATCH_JOB_EXECUTION可以运行,即使所有的BATCH_JOB_EXECUTION项是完成状态。
所以我想我有两个问题——这是正确的行为吗?如果是这样,是什么阻止了 BATCH_JOB_EXECUTION_PARAMS 被删除,我该如何删除它们?
JobParametersValidator在您的情况下,bean在downloadValidator作业开始之前运行。
在您的情况下发生的情况是您传递给作业的参数与“放大”的参数相同JobInstance。然而,由于该工作以戏剧性的方式失败,因此它可能没有进入失败状态。
您可以使用不同的参数运行作业(以获取新的作业实例),或者尝试在重新启动之前在 BATCH_STEP_EXECUTION 或 BATCH_JOB_EXECUTION 中将前一个步骤/作业的状态更新为 FAILED。
更新(问题中添加了新信息)
您必须小心这里的工作流程。是的,您的步骤失败了,但是您的上下文文件表明该作业应该END在CONTINUE.
<batch:next on="CONTINUE" to="job.download-stuff.process-stuff.step" />
<batch:end on="*" />
Run Code Online (Sandbox Code Playgroud)
首先,要非常小心以 结尾*。在您的场景中,它会导致您完成工作(“成功” ExitCode)FAILED。另外,ExitCode成功步骤的默认值是COMPLETED, 不是CONTINUE,所以要小心。
<!-- nothing to me indicates you'd get CONTINUE here, so I changed it -->
<batch:next on="COMPLETED" to="job.download-stuff.process-stuff.step" />
<!-- if you ever have reason to stop here -->
<batch:end on="END" />
<!-- always fail on anything unexpected -->
<batch:fail on="*" />
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10468 次 |
| 最近记录: |