Spring Batch:即使使用 Never RetryPolicy,块步骤也会在编写器中重试异常

SpringBatch: ChunkStep retried on exception in writer even with NeverRetryPolicy

我在 Spring 批处理中配置了一个 ChunkStep,如下所示:

stepBuilderFactory
    .get( "myStep" )
    .<I, O> chunk( 1 )
    .transactionManager( txManager )
    .faultTolerant()
    .skipPolicy( new AlwaysSkipItemSkipPolicy() )
    .retryPolicy( new NeverRetryPolicy() )
    .listener( stepSkipListener )
    .reader( someReader ).processor( someProc ).writer( someWriter );

一个项目一个项目地处理,如果处理器或编写器中出现异常,则只记录它。

不幸的是,编写器抛出的第一个异常甚至没有发送给侦听器,而是重试了项目(处理器和编写器)。

我必须如何配置块步骤才能跳过该项目?

查看您的代码,我认为您的情况与以下类似:https://github.com/spring-projects/spring-batch/issues/2071. Quoting Dr Dave Syer from this comment:

A skip is still (and always probably will be) a recovery option for an exhausted retry

我同意这一点。因此,使用 "Always skip" 策略和 "Never retry" 策略实际上是不兼容的。

从技术上讲,当块扫描被激活时(也就是抛出可跳过的异常时),每个项目 re-processed/re-written 在它自己的事务中(提交间隔在幕后(重新)设置为 1 并且块逐项重新处理)。换句话说,ChunkProcessor,更准确地说是 FaultTolerantChunkProcessor 在你的情况下(由 ItemProcessor + ItemWriter 组成)被重新应用于块的每个项目.

因此您可能认为您的物品已被重试(尽管使用 NeverRetryPolicy),但这实际上是块扫描过程的一部分(与跳过策略相关)。

Unfortunately the first exception thrown by the writer is not even sent to the listener

不应该是这样的。您可以在此处找到示例:。请注意,使用 stepBuilderFactory 时方法调用的顺序可能很重要,因为这些方法 return 不同类型的构建器,因此我邀请您尝试:

stepBuilderFactory
    .get( "myStep" )
    .<I, O> chunk( 1 )
    .reader( someReader ).processor( someProc ).writer( someWriter )
    .faultTolerant()
    .skipPolicy( new AlwaysSkipItemSkipPolicy() )
    .listener( stepSkipListener );