首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ItemWriter的Spring Batch跳过异常

ItemWriter的Spring Batch跳过异常
EN

Stack Overflow用户
提问于 2014-03-20 11:07:44
回答 2查看 23.1K关注 0票数 9

我正在尝试使用带有Java配置的Spring Batch 2.2.5。下面是我的配置:

代码语言:javascript
复制
@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();
    }
....


}

使用上面的配置,如果项编写器(由documentMetadataFileMigrator指向的bean )抛出'DocumentImportException',那么异常将不会被跳过。Spring Batch实际上会再次重试相同的输入。也就是说,它将对“documentPackageFileValidationProcessor”使用相同的输入。

但是,如果我将项编写器中的逻辑移动到项处理器中:

代码语言:javascript
复制
 @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’返回的项)。

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

谢谢大家,如果这是一个基本的问题,我要道歉。

诚挚的问候,

亚历克斯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-20 21:14:08

这种行为是正确的。ItemWriter接收要写入的项的列表。如果抛出了一个可跳过的异常,Spring Batch会尝试确定是哪个项目导致了该异常,因此只跳过该项目。完成此操作的方法是回滚事务,将提交间隔更改为1,然后重新处理每个项目,并再次尝试写入。这只允许跳过有错误的项,而不需要跳过整个块。

这里讨论了同样的问题(仅使用XML config):How is the skipping implemented in Spring Batch?

票数 14
EN

Stack Overflow用户

发布于 2014-03-21 05:58:37

最后,这就是我的工作-如果我想使用itemwriter,而不需要对相同的项目进行重新处理:

代码语言:javascript
复制
 @Bean
    @Autowired
    public Step procesingStep() {
           CompositeItemProcessor<DocumentPackageFileMetadata, DocumentPackageFileMetadata> compositeProcessor = new CompositeItemProcessor<DocumentPackageFileMetadata, DocumentPackageFileMetadata>();
           compositeProcessor.setDelegates(Lists.newArrayList(
                   documentPackageFileValidationProcessor(),
                   documentPackageFileExtractionProcessor(),
                   documentMetadataFileTransformer()
           ));
        return stepBuilder.get("procesingStep")
                .<DocumentPackageFileMetadata, DocumentPackageFileMetadata>chunk(1)
                .reader(documentPackageFileReader())
                .processor(compositeProcessor)
                .writer(documentMetadataFileMigrator())
                .faultTolerant()
                .skip(DocumentImportException.class)
                .noRetry(DocumentImportException.class)
                .noRollback(DocumentImportException.class)
                .skipLimit(10)
                .listener(skipListener())
                .listener(documentPackageReadyForProcessingListener())
                .listener(stepExecutionListener())
                .build();
    }

注意,我已经指定了'noRetry‘和'noRollback’。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22522681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档