【发布时间】:2016-08-31 11:38:25
【问题描述】:
我正在尝试解决 Spring Batch 中最近一直困扰我们系统的问题。我们有一份工作,在大多数情况下工作得很好。这是一个下载和处理数据的多步骤作业。
问题是有时这项工作会失败。也许我们尝试连接的服务器会抛出错误,或者我们在工作过程中关闭了服务器。此时,我们的quartz 调度程序下次尝试运行该作业时它似乎没有做任何事情。以下是该职位定义的精简版:
<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>
一旦进入此状态,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 批处理调用了该验证器并且它成功通过(设置断点并逐步通过)。第一步没有执行。
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;
}
我确认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 被删除,我该如何删除它们?
【问题讨论】:
标签: spring spring-batch