gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 21:22:48 25 4
gpt4 key购买 nike

我有一个 Spring 批处理程序。

跳过限制设置为 5, block 大小为 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>

SkipPolicy 类如下:
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;
}
}

因此,对于在达到跳过限制之前发生的任何错误,跳过策略将忽略该错误(返回 true)。达到跳过限制后,作业将因任何错误而失败。

mySkipListener 类如下:
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());
}
}

现在在 myItemProcessor 我有以下代码块:
if (item.getTheNumber().charAt(4) == '-') {
item.setProductNumber(item.getTheNumber().substring(0, 3));
} else {
item.setProductNumber("55");
}

对于某些项目,Number 字段为空,因此上面的代码块会引发“StringIndexOutofBounds”异常。

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

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

如果跳过限制超过错误数(即 > 6),则跳过监听器类中的 sys 输出将被调用并报告跳过的错误。

但是,如果跳过限制较少(例如我的示例中的 5),则跳过监听器类中的 sys 输出根本不会被调用,我会直接在控制台上获得以下异常转储:
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)

这种行为背后的原因是什么?我应该怎么做才能解决这个问题?

谢谢阅读!

最佳答案

如果包含它的 tasklet 正常完成,则 SkipListener 仅在 Chunk 的末尾使用。当您有超过跳过限制的错误时,通过您看到的异常报告,并且 tasklet 被中止。

如果错误数量小于跳过限制,则 tasklet 正常完成,并且为每个跳过的行或项目调用一次 SkipListener - Spring Batch 在内部构建它们的列表,但仅在最后报告。

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

如您所见,简单的解决方案是使跳过限制足够大。同样的想法是,如果您必须跳过很多项目,则可能存在更严重的问题。

关于spring-batch - Spring 批处理中关于跳过策略实现的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9174516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com