comportement étrange spring batch sur skip mise en œuvre des politiques
J'ai un printemps programme de commandes.
L'ignorer limite est de 5 et la taille de bloc est de 1000.
J'ai un travail en deux étapes comme ci-dessous:
<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>
Le saut de la politique est comme ci-dessous:
<beans:bean id="skipPolicy" class="com.myPackage.util.Skip_Policy">
<beans:property name="skipLimit" value="5"/>
</beans:bean>
La SkipPolicy classe est comme ci-dessous:
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;
}
}
Ainsi que pour toute erreur survenant avant l'ignorer limite est atteinte, le skip politique ignorer l'erreur (return true). Le travail échoue pour toute erreur après le saut de la limite est atteinte.
La mySkipListener classe est comme ci-dessous:
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());
}
}
Maintenant dans myItemProcessor j'ai ci-dessous bloc de code:
if (item.getTheNumber().charAt(4) == '-') {
item.setProductNumber(item.getTheNumber().substring(0, 3));
} else {
item.setProductNumber("55");
}
De certains des éléments lenombre champ est null et donc au-dessus du bloc de code jette "StringIndexOutofBounds" l'exception".
Mais je vois un comportement étrange dont je ne suis pas à comprendre pourquoi il se passe.
En tout il y a 6 éléments qui sont d'avoir d'erreur c'est à dire le nombre de niveaux de champ est null.
Si le skip limite est plus que le nombre d'erreurs (c'est à dire > 6), le sys sorties en ignorer l'auditeur classe sont appelé et les erreurs se sont glissées sont signalés.
Toutefois, si le skip limite est de moins en moins (disons 5 comme dans mon exemple), le sys sorties en ignorer l'auditeur de la classe ne sont pas d'être appelé à tout et je suis arriver directement au-dessous de vidage d'exception sur console:
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)
Quelle est la raison derrière ce comportement ? Que dois-je faire pour résoudre ce problème ?
Merci pour la lecture!
OriginalL'auteur Vicky | 2012-02-07
Vous devez vous connecter pour publier un commentaire.
La SkipListener est uniquement utilisé à la fin de la partie, si la tasklet qui contient elle se termine normalement. Lorsque vous avez plus d'erreurs que le skip-limite, qui est signalée, via l'exception que vous voyez, et la tasklet est abandonnée.
Si le nombre d'erreurs est inférieur au skip-limite, alors la tasklet termine normalement et le SkipListener est appelée une fois pour chaque sauté de ligne ou d'un élément - Spring Batch crée une liste d'entre eux en interne au fur et à mesure, mais seulement des rapports à la fin.
L'idée si ce n'est que si la tâche échoue, vous sont, probablement, va réessayer, en sachant ce qui l'a ignorée pendant incomplète n'est pas utile, chaque fois que vous recommencez, vous obtiendrez la même notification. Seulement si tout réussit, vous faire voir ce qui a été ignoré. L'imagerie de vous connecter a l'sauté éléments, vous ne voulez pas être connecté en tant que sautées et une fois de plus.
Comme vous l'avez vu, la solution simple est de faire le skip-limite assez grand. Encore une fois l'idée est que si vous avez à sauter beaucoup d'éléments, il y a probablement un problème plus grave.
OriginalL'auteur Paul