Spring Batch分区无法按预期工作

时间:2019-05-09 02:29:10

标签: java hibernate spring-boot spring-batch

我有一个春季批处理分区工作。基本上,这样做是将处理db中的数据行并提供一些输出。但是我得到的日志无法正确对其进行分区。记录表已处理并显示结果标志,当完成处理时,会将结果标志设置为Y,已处理标志仍为N。由于itemreader正在对已处理标志进行选择,所以我不想在处理过程中更改它。这就是为什么我添加结果标志。完成该分区作业后,将有另一个作业设置为要处理的结果。

@Bean
@StepScope
public dbItemReader(@Value("${executionContext[from]}") Long from, @Value("${executionContext[to]}") Long to,
    @Value("${executionContext[partitionId]}") Long partitionId){
        RepositoryItemReader<Record>  itemReader = new RepositoryItemReader<>();
        itemReader.setRepository(dataRepo);
        //Select record from Record record where processed=:processed and rownum >=:from and rownum < :to;
        itemReader.setMethod("findByProcessedBetweenFromAndTo");
        List<Object> params = new ArrayList<>();
        params.put("N");
        params.put(from);
        params.put(to);
        itemReader.setArguments(params);
        return itemReader;
}

@Bean
public dbItemProcessor(){
        RecordItemProcessor<Record>  itemProcessor = new RecordItemProcessor<>();
        return itemProcessor;
}

@Bean
public writer(){
    RepositoryItemWriter writer = new RepositoryItemWriter();
    writer.setRepository(dataRepo);
    writer.setMethod("save");
    return writer;
}

@Bean
public Partition partitioner() {
    Partition p = new Partition();
    p.setTotalCount(dataRepo.count());
    return p;
}

//Partition class just @override method
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
    Map<String, ExecutionContext> map = new HashMap<>(gridSize);
    int start = 1;
    int range = this.totalCount / gridSize + 1;
    for (int i=0; to gridSize) {
        ExecutionContext context = new ExecutionContext();
        context.putString("from", start);
        context.putString("to", start + range);
        context.putString("partitionId", i);
        start += range;
        map.put("Partition"+ i, context);
    }
    return map;
} 

@Bean
public Step slaveStep() 
  throws UnexpectedInputException, MalformedURLException, ParseException {
    return steps.get("slaveStep").<Record, Record>chunk(1)
      .reader(dbItemReader(null,null,null))
      .processor(dbItemProcessor())
      .writer(itemWriter())
      .build();
}

@Bean
public Step partitionStep() 
  throws UnexpectedInputException, MalformedURLException, ParseException {
    return steps.get("partitionStep")
      .partitioner("slaveStep", partitioner())
      .step(slaveStep())
      .taskExecutor(taskExecutor())
      .gridSize(10)
      .build();
}

//omit job setup

上面是示例代码,整个想法是我将整个db划分为10个分区,比如totalCount为100,每个分区将读取1-10、10-20,依此类推。因此最后将处理所有100个并将Result设置为Y。但是,当该分区作业完成时,仍有记录具有result = N,这意味着跳过了某些记录。

当我检查日志时,itemprocessor正在以某种方式处理重复记录

Thread 10 - Info: Processing record: 2
Thread 4 - Info: Processing record: 40
Thread 3 - Info: Processing record: 20
so  on
//after some time, there will be threads reading the same record again
Thread 5 - Info: Processing record: 20 //it suppose process 60-70 for example

我在想,如果将数据划分为10个分区,每个分区都应该有自己的一组数据要处理,并且永远不要接触另一组数据。 对?分区的用途是什么?按钮行是应该处理的所有数据。有多个分区作业,它们可能同时运行。

我不知道自己做错了什么,所以我需要一些帮助。

0 个答案:

没有答案