Spring Batch sauter exception pour ItemWriter
Je suis en train d'utiliser Spring Batch 2.2.5 avec Java config. Voici la config que j'ai:
@Configuration
@EnableBatchProcessing
public class JobConfiguration {
@Autowired
private JobBuilderFactory jobBuilder;
@Autowired
private StepBuilderFactory stepBuilder;
@Bean
@Autowired
public Job processDocumentsJob() {
return jobBuilder.get("processDocumentsJob")
.start(procesingStep())
.build();
}
@Bean
@Autowired
public Step procesingStep() {
CompositeItemProcessor<File, DocumentPackageFileMetadata> compositeProcessor = new CompositeItemProcessor<File, DocumentPackageFileMetadata>();
compositeProcessor.setDelegates(Lists.newArrayList(
documentPackageFileValidationProcessor(),
documentMetadataFileTransformer()
));
return stepBuilder.get("procesingStep")
.<File, DocumentPackageFileMetadata>chunk(1)
.reader(documentPackageFileReader())
.processor(compositeProcessor)
.writer(documentMetadataFileMigrator())
.faultTolerant()
.skip(DocumentImportException.class)
.skipLimit(10)
.listener(stepExecutionListener())
.build();
}
....
}
Avec la config ci-dessus, si le itemwriter (la fève pointé par documentMetadataFileMigrator) renvoie 'DocumentImportException', alors, l'exception ne sera pas ignorée. Spring Batch sera effectivement réessayer la même entrée. c'est à dire qu'il va utiliser la même entrée contre "documentPackageFileValidationProcessor'.
Mais, si je déplace la logique à l'intérieur de la itemwriter dans un itemprocessor:
@Bean
@Autowired
public Step procesingStep() {
CompositeItemProcessor<File, DocumentPackageFileMetadata> compositeProcessor = new CompositeItemProcessor<File, DocumentPackageFileMetadata>();
compositeProcessor.setDelegates(Lists.newArrayList(
documentPackageFileValidationProcessor(),
documentMetadataFileTransformer(),
documentMetadataFileMigratorAsProcessor() //same as itemwriter, but implemented as itemprocessor
));
return stepBuilder.get("procesingStep")
.<File, DocumentPackageFileMetadata>chunk(1)
.reader(documentPackageFileReader())
.processor(compositeProcessor)
.faultTolerant()
.skip(DocumentImportException.class)
.skipLimit(10)
.listener(stepExecutionListener())
.build();
}
alors, l'exception sera ignoré correctement. c'est à dire Spring Batch ne sera pas réessayer la même élément contre 'documentPackageFileValidationProcessor'. Il va aller à l'élément suivant (celui retourné à partir de 'documentPackageFileReader').
Est-ce un bug sur Spring Batch, ou est-elle satisfaisante? Si oui, quelqu'un peut me pointer à la documentation pertinente?
Merci les gars, et excuses si cette question est fondamentale.
Cordialement,
Alex
OriginalL'auteur caffeine_inquisitor | 2014-03-20
Vous devez vous connecter pour publier un commentaire.
Que le comportement est correct. Le ItemWriter reçoit une liste d'articles à écrire. Si un désactivables exception est levée, Spring Batch tente de déterminer à quel point effectivement causé l'exception seulement cet élément est ignoré. La manière dont c'est fait est, la transaction est annulée, l'intervalle de validation est changé à 1, et chaque élément est ensuite retraité et l'écriture s'est essayé à nouveau. Cela permet uniquement l'élément avec l'erreur d'ignorer au lieu de devoir passer la totalité de la partie.
Cette même question est abordée ici (uniquement à l'aide de XML de config): Comment est le saut en œuvre dans Spring Batch?
J'ai juste fait par le biais de l'application de nouveau. Je sais maintenant pourquoi il na pas traiter le reste des éléments. C'est parce que lors de la relance, de l'un des itemprocessor lever une exception qui n'est pas désactivables. Je suis bête! Merci pour le pointeur, Michael
En fait... venez à penser de nouveau - si la taille de bloc est de 1, alors qu'il ne devrais pas avoir besoin de revenir en arrière et recommencez l'ensemble de la chaîne de nouveau juste pour comprendre à quel élément provoque une erreur, non? Je veux dire... si la taille de bloc est de 1, et la configuration est ignorer l'exception, pas de nouvelle tentative pour que l'exception... puis juste aller de l'avant et processus de l'élément suivant.
Le ItemWriter#écrit méthode reçoit une liste d'éléments. Sans passer par un à la fois, il n'y a aucun moyen pour nous de déterminer ce qui dans la liste a jeté l'exception de l'écrivain. Tous le cadre le sait, c'est que quelque chose dans cette liste causé de quelque chose de casser.
Pour moi, en quelque sorte, c'est se comporter un peu différemment. Dites, j'ai 4 dossiers à lire-traitées à l'écriture du morceau de taille de 10. Enregistrement-2 a un certain problème en ce qui jette un désactivables exception pendant le "processus" de l'état. Il saute correctement, mais n'écrit que de l'Enregistrement 3 Enregistrement et 4. Enregistrement-1 qui a été correctement lu & traitement, n'est pas écrit du tout. Quel est le problème?
OriginalL'auteur Michael Minella
À la fin, c'est ce qui est de travailler pour moi - si je veux utiliser itemwriter, sans retraitement de la même élément:
Remarque que j'ai spécifié "noRetry" et "noRollback'.
OriginalL'auteur caffeine_inquisitor