我想知道如何在ItemWriter中确定Spring Batch当前处于块处理模式还是回退单项处理模式。首先,我没有找到有关该后备机制如何实现的信息。

即使我还没有找到解决我实际问题的解决方案,我也想与您分享我关于后备机制的知识。

如果我错过了任何事情,请随时添加其他信息的答案;-)

最佳答案

可以在FaultTolerantChunkProcessorRetryTemplate中找到跳过机制的实现。

假设您配置了skippable exceptions,但没有配置retryable exceptions。并且当前块中有一个失败的项目导致异常。

现在,首先将整个块写入。在处理器的write()方法中,您可以看到RetryTemplate被调用。它还获得了对RetryCallbackRecoveryCallback的两个引用。

切换到RetryTemplate。查找以下方法:

protected <T> T doExecute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback, RetryState state)

在那里,您可以看到RetryTemplate只要没有用尽即可重试(即在我们的配置中恰好一次)。这样的重试将由可重试的异常引起。不可重试的异常将在此处立即中止重试机制。

重试用尽或中止后,RecoveryCallback将被调用:
e = handleRetryExhausted(recoveryCallback, context, state);

这就是现在开始单项处理模式的地方!

RecoveryCallback(在处理器的write()方法中定义!)将锁定输入块(inputs.setBusy(true))并运行其scan()方法。在那里,您可以看到从块中取出了一个项目:
List<O> items = Collections.singletonList(outputIterator.next());
如果ItemWriter可以正确处理此单个项目,则该块将完成,并且ChunkOrientedTasklet将运行另一个块(用于下一个单个项目)。这将导致对RetryCallback的常规调用,但是由于该块已被RecoveryTemplate锁定,因此会立即调用scan()方法:
if (!inputs.isBusy()) {
    // ...
}
else {
    scan(contribution, inputs, outputs, chunkMonitor);
}

因此,将处理另一个单个项目并将其重复进行,直到原始块逐个项目已被处理:
if (outputs.isEmpty()) {
    inputs.setBusy(false);

就是这样。希望对您有所帮助。而且,我甚至更希望您可以通过搜索引擎轻松找到它,而不会浪费太多时间,自己找到它。 ;-)

09-26 20:28