ItemWriter 的 Spring Batch 跳过异常 [英] Spring Batch skip exception for ItemWriter

查看:20
本文介绍了ItemWriter 的 Spring Batch 跳过异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Java 配置中使用 Spring Batch 2.2.5.这是我的配置:

I'm trying to use Spring Batch 2.2.5 with Java config. Here is the config that I have:

@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();
    }
....


}

使用上面的配置,如果 itemwriter(由 documentMetadataFileMigrator 指向的 bean)抛出DocumentImportException",则不会跳过该异常.Spring Batch 实际上会再次重试相同的输入.即它将对documentPackageFileValidationProcessor"使用相同的输入.

With the config above, if the itemwriter (the bean pointed by documentMetadataFileMigrator) throws 'DocumentImportException', then the exception wont be skipped. Spring Batch will actually retry the same input again. i.e. it will use the same input against 'documentPackageFileValidationProcessor'.

但是,如果我将 itemwriter 内部的逻辑移动到 itemprocessor 中:

But, if I move the logic inside the itemwriter into an 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();
        }

然后异常将被正确跳过.即 Spring Batch 不会针对documentPackageFileValidationProcessor"重试相同的项目.它将转到下一个要处理的项目(从'documentPackageFileReader' 返回的那个).

then the exception will be skipped correctly. i.e. Spring Batch will not retry the same item against 'documentPackageFileValidationProcessor'. It will go to the next item to process (the one returned from 'documentPackageFileReader').

这是 Spring Batch 上的一个错误,还是它的行为符合预期?如果是这样,有人能给我指点相关文档吗?

Is this a bug on Spring Batch, or is it behaving as expected? If so, can someone point me to the relevant documentation?

谢谢大家,如果这是一个基本问题,请道歉.

Thanks guys, and apology if this is a fundamental question.

最好的问候,

亚历克斯

推荐答案

这种行为是正确的.ItemWriter 接收要写入的项目列表.如果抛出可跳过的异常,Spring Batch 会尝试确定实际导致异常的项目,以便仅跳过该项目.这样做的方式是回滚事务,将提交间隔更改为 1,然后重新处理每个项目并再次尝试写入.这允许只跳过有错误的项目而不是需要跳过整个块.

That behavior is correct. The ItemWriter receives a list of items to write. If a skippable exception is thrown, Spring Batch attempts to determine which item actually caused the exception so only that item is skipped. The way this is done is the transaction is rolled back, the commit interval is changed to 1, and each item is then reprocessed and the write is attempted again. This allows only the item with the error to be skipped instead of needing to skip the entire chunk.

这里讨论了同样的问题(仅使用 XML 配置):Spring Batch 中的跳过是如何实现的?

This same issue is discussed here (only using XML config): How is the skipping implemented in Spring Batch?

这篇关于ItemWriter 的 Spring Batch 跳过异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆