Spring batch spring批处理中有关跳过策略实现的奇怪行为

Spring batch spring批处理中有关跳过策略实现的奇怪行为,spring-batch,Spring Batch,我有一个spring批处理程序 跳过限制设置为5,块大小为1000 我的工作包括以下两个步骤: <step id="myFileGenerator" next="myReportGenerator"> <tasklet transaction-manager="jobRepository-transactionManager"> <chunk reader="myItemReader" processor="myIte

我有一个spring批处理程序

跳过限制设置为5,块大小为1000

我的工作包括以下两个步骤:

    <step id="myFileGenerator" next="myReportGenerator">
        <tasklet transaction-manager="jobRepository-transactionManager">
            <chunk reader="myItemReader" processor="myItemProcessor" writer="myItemWriter"  commit-interval="1000" skip-policy="skipPolicy"/>
        </tasklet>
        <listeners>
            <listener ref="mySkipListener"/>
        </listeners>
    </step>

    <step id="myReportGenerator">
        <tasklet ref="myReportTasklet" transaction-manager="jobRepository-transactionManager"/>
    </step> 
<beans:bean id="skipPolicy" class="com.myPackage.util.Skip_Policy">
    <beans:property name="skipLimit" value="5"/>
</beans:bean>
public class Skip_Policy implements SkipPolicy {

private int skipLimit;

public void setSkipLimit(final int skipLimit) {
    this.skipLimit = skipLimit;
}

public boolean shouldSkip(final Throwable t, final int skipCount) throws SkipLimitExceededException {

    if (skipCount < this.skipLimit) {
        return true;
    }
    return false;
}
}
public class mySkipListener implements SkipListener<MyItem, MyItem> {

public void onSkipInProcess(final MyItem item, final Throwable t) {
    // TODO Auto-generated method stub
    System.out.println("Skipped details during PROCESS is: " + t.getMessage());
}

public void onSkipInRead(final Throwable t) {

    System.out.println("Skipped details during READ is: " + t.getMessage());
}

public void onSkipInWrite(final MyItem item, final Throwable t) {
    // TODO Auto-generated method stub
    System.out.println("Skipped details during WRITE is: " + t.getMessage());
}
}
对于某些项,数字字段为空,因此上面的代码块抛出“StringIndexOutofBounds”异常

但我看到了一种奇怪的行为,我不明白为什么会发生这种事

总共有6项有错误,即数字字段为空

如果跳过限制大于错误数(即>6),将调用skip listener类中的sys out并报告跳过的错误

但是,如果跳过限制较小(例如,在我的示例中为5),则根本不会调用skip listener类中的sys out,我将直接在控制台上获得以下异常转储:

org.springframework.batch.retry.RetryException: Non-skippable exception in recoverer while processing; nested exception is java.lang.StringIndexOutOfBoundsException
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$2.recover(FaultTolerantChunkProcessor.java:282)
at org.springframework.batch.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:416)
at org.springframework.batch.retry.support.RetryTemplate.doExecute(RetryTemplate.java:285)
at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:187)
这种行为背后的原因是什么?我应该如何解决这个问题


谢谢你的阅读

如果包含SkipListener的tasklet正常完成,则只能在块的末尾使用它。当您的错误超过跳过限制(即通过您看到的异常报告的错误)时,tasklet将中止

如果错误数小于跳过限制,则tasklet将正常完成,并为每个跳过的行或项调用SkipListener一次-Spring Batch会在执行过程中在内部生成一个它们的列表,但只在最后报告

如果这是因为如果任务失败,您可能会重试,因此知道在未完成的运行期间跳过了什么是没有用的,每次重试都会收到相同的通知。只有在其他一切都成功的情况下,您才能看到跳过了什么。如果您正在记录跳过的项目,则不希望它们被一次又一次地记录为跳过

如您所见,简单的解决方案是使跳过限制足够大。同样的想法是,如果你不得不跳过很多项目,可能会有更严重的问题

org.springframework.batch.retry.RetryException: Non-skippable exception in recoverer while processing; nested exception is java.lang.StringIndexOutOfBoundsException
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$2.recover(FaultTolerantChunkProcessor.java:282)
at org.springframework.batch.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:416)
at org.springframework.batch.retry.support.RetryTemplate.doExecute(RetryTemplate.java:285)
at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:187)