使用PagingAndSortingRepository进行Spring批处理分区

时间:2016-07-05 05:03:33

标签: java spring spring-batch

我正在尝试配置Spring Batch Steps进行分区。找到的好示例here显示了一个关于“id范围”的分区,但我不知道从哪里开始“数据页”范围。

在我的顺序步骤中,我有:

  • reader:使用PagingAndSortingRepository的RepositoryItemReader
  • 处理器:数据转换器
  • writer:使用CrudRepository的RepositoryItemWriter
  • chunck:5
  • listener:StepListener

return stepBuilderFactory.get("stepApplicationForm") .<OldApplicationForm, NewApplicationForm>chunk(5) .reader(reader).processor(processor).writer(writer) .listener(listener).build();

正如我所理解的,对于分区,我必须创建一个分区器,然后我有一个“父”步骤告诉使用带有子步骤的分区器,然后是“子”步骤,读者知道“分页“参数。

对于TaskExecutor,我认为ThreadPoolTaskExecutor适合。

基于数据“页面”实现/配置分区的好方法是什么?我应该检查什么是线程洞穴?

谢谢:)

1 个答案:

答案 0 :(得分:1)

每个分区都有自己的项目阅读器和项目编写器实例。您的分区实现将找到数据加载的最小值。使用您自己的逻辑,您可以在执行上下文中创建最小值和最大值。在查询数据库时,您可以利用这些来处理特定的数据片段,以免发生并发问题。

@Bean
public Step myMasterStep() {
    return  stepBuilderFactory.get("myMasterStep")
            .partitioner("mySlaveWorker", myPartitioner())
            .partitionHandler(myPartitionHandler()).build();
}


@Bean
    public Step mySlaveWorker() {
        return stepBuilderFactory
                .get("mySlaveWorker")
                .<OldApplicationForm, NewApplicationForm> chunk(5)
                .faultTolerant()
                .listener(MyStepListener())
                .skip(DataAccessException.class)
                .skip(FatalStepExecutionException.class)
                .skip(Exception.class)
                .skipLimit(75)
                .noRollback(DataAccessException.class)
                .noRollback(FatalStepExecutionException.class)
                .noRollback(Exception.class)
                .reader(myDataItemReader())
                .writer(myDataItemWriter()).build();
    }

@Bean
@StepScope
public MyDataItemReader myDataItemReader(
        @Value("#{stepExecutionContext[minId]}") Long minId,
        @Value("#{stepExecutionContext[maxId]}") Long maxId) {
    MyDataItemReader myDataItemReader = new MyDataItemReader();
    myDataItemReader.setPageSize(100);
    myDataItemReader.setMinId(minId);
    myDataItemReader.setMaxId(maxId);
    return myDataItemReader;
}

@Bean
@StepScope
public MyDataItemWriter myDataItemWriter() {
    return new MyDataItemWriter();
}

@Bean
@StepScope
public MyPartitioner myPartitioner() {
    MyPartitioner myPartitioner = new MyPartitioner();
    myPartitioner.setDataSource(dataSource);
return myPartitioner;
}

public class MyStepListener implements SkipListener<OldApplicationForm, NewApplicationForm> {

private static final Logger LOGGER = LoggerFactory.getLogger(MyStepListener.class);


public void onSkipInProcess(OldApplicationForm item, Throwable t) {
    LOGGER.error("onSkipInProcess" + t.getMessage());
}

public void onSkipInRead(Throwable t) {
    LOGGER.error("onSkipInRead " + t.getMessage());
}


public void onSkipInWrite(NewApplicationForm item, Throwable t) {
    //logs
    LOGGER.error("In MyStepListener --> onSkipInProcess" + t.getMessage());
}

}