Eri*_*ria 5 java spring spring-batch spring-boot
我使用 Spring Boot 创建了一个批处理。这是批处理的主要配置类:
@Configuration
@EntityScan({"my.domain"})
@EnableJpaRepositories({"my.domain"})
@EnableBatchProcessing
public class BatchConfiguration {
/** Motif d'identification des fichiers d'entrée */
@Value("${batch.input-file-pattern}")
private String inputFilePattern;
@Bean
public BatchConfigurer configurer( EntityManagerFactory entityManagerFactory ){
return new MapForcedBatchConfigurer( entityManagerFactory );
}
@Bean
public Job myJob( JobBuilderFactory jobs, Step step1 ){
return jobs.get("myJob")
.incrementer( new RunIdIncrementer() )
.flow( step1 )
.end()
.build();
}
@Bean
public Step step1( StepBuilderFactory stepBuilderFactory,
StepExecutionListener stepExecutionListener,
ItemReader<Input> myReader,
ItemProcessor<Input, Dto> myProcessor,
ItemWriter<Dto> myWriter ){
return stepBuilderFactory.get("myStep")
.listener( stepExecutionListener )
.<Input, Dto> chunk(1)
.reader( myReader )
.processor( myProcessor )
.writer( myWriter )
.faultTolerant().skipPolicy( new MySkipPolicy() ).retryLimit( 0 )
.build();
}
@Bean
public StepExecutionListener stepListener() {
return new MyStepExecutionListener();
}
@Bean
public ItemReader<Input> myReader() throws IOException {
return new MyItemReader( inputFilePattern );
}
@Bean
public ItemProcessor<Input, Dto> myProcessor(){
return new MyItemProcessor();
}
@Bean
public ItemWriter<Dto> myWriter(){
return new MyItemWriter();
}
}
Run Code Online (Sandbox Code Playgroud)
当处理一个项目发生错误时,记录器写一条消息,然后批处理处理下一个元素。这正是我想要的。
但是当写入项目发生错误时,批处理总是重试一次操作!这样我每个写入错误都有 2 个错误日志。
无论错误发生在步骤的哪个部分,如何将批处理配置为从不重试错误?
这篇文章解释了以下内容:
【当我们在写的时候有一个skip】,框架必须找出是哪个项目导致了失败。对于读取项目的缓存列表中的每个项目,它启动一个自己的事务。项目由 ItemProcessor 处理,然后由 ItemWriter 写入。如果没有错误,则提交包含一项的 mini-chunk,下一项继续迭代。我们期望至少有一个可跳过的异常,当发生这种情况时,事务将回滚并将该项目标记为跳过的项目。一旦我们的迭代完成,我们就继续正常的块处理。
它可以是对重新执行写入操作的解释。我希望我能以某种方式绕过这种行为......
我认为如果没有子类化,你就没有什么可以做的 FaultTolerantChunkProcessor。调用readerIsTransactionalQueue()步骤构建器会强制执行您想要的行为,但它会忽略所有异常(不会调用您的跳过策略)。
原因是 Spring Batch 尝试确定导致错误的项目,即使您的块只有一个项目,算法也不会考虑它(事实上,为什么您使用大小为 1 的块?... )
您可以做的就是自己在编写器中捕获异常。您甚至可以ItemWriter为此唯一的目的写一个包装。
| 归档时间: |
|
| 查看次数: |
4057 次 |
| 最近记录: |