0

我已经创建了多个作业,并且我在一个循环中运行多个作业,我要求按顺序运行这些作业,但是所有步骤的项目阅读器都在运行,然后所有作业的项目编写器都在按顺序运行,是否有任何解决方案,以便当作业的项目阅读器和项目编写器完成,然后控制转到另一个作业。

示例代码如下

public void jobprocess() throws Exception {
        List<Job> jobList = BatchJob.fetchAllJobs();
        for(Job job:jobList){            
            jobLauncher.run(job, params);
        }

    }
    
    public List<Job> fetchAllJobs() throws Exception {
            List<Object> list = service.findAll();
            List<Job> jobBuilderList = new ArrayList<>();
            int i = 0;
            for(Object obj:list){
    
                Step step = stepBuilderFactory.get("step"+i)
                    .<Student, Student>chunk(500)
                    .reader(ListItemReaderV2(obj))
                    .processor(Processor)
                    .writer(Writer)
                    .build();
    
                jobBuilderList.add(jobBuilderFactory.get("job"+i)
                    .incrementer(new RunIdIncrementer())
                    .listener(this)
                    .start(step)
                    .build());
                i++;
    
            }
            return jobBuilderList;
        }
4

2 回答 2

0

您应该构建一个超级作业,将您的多个作业封装为步骤。通过这种方式,您可以要求 Spring 批处理按顺序运行这些步骤(因此是您的作业)。在 Spring 批处理中,有一个特定的步骤 ( JobStep) 允许这样做:


public void  jobprocess() throws Exception {
    jobLauncher.run(superJob(), params);
}

public Job superJob(){
   List<Step> stepList = BatchJob.fetchAllJobs().stream()
                                           .map(j-> stepBuilderFactory.get(j.getName())
                                                        .job(j)
                                                        .build()
                                            ).collect(Collectors.toList());
   SimpleJobBuilder simpleJobBuilder=jobBuilderFactory.get("superJob")
                                                      .start(stepList.get(0));
   for(int i = 1; i < stepList.size() ; i++){
        simpleJobBuilder.next(stepList.get(i))
   }
   return simpleJobBuilder.build();
}

对旧式循环编码感到抱歉:这是我看到的排除stepList. 请注意,我使用了将父作业参数注入每个 JobStep 的默认行为(参见https://docs.spring.io/spring-batch/docs/4.2.x/api/org/springframework/batch/core/step /job/JobStep.html#setJobParametersExtractor-org.springframework.batch.core.step.job.JobParametersExtractor- )

于 2020-08-11T08:50:42.393 回答
0

经过大量实验,我发现这个问题是由于在作业类中使用了 ListItemReader() 方法。

ListItemReader<Object> listItemReader(object obj) {
 return new ListItemReader<>(service.getList()); }

在上面的实现中,listItemReader() 方法甚至在作业开始之前调用,并且作业在执行 listItemReader() 方法之后开始。

现在我通过实现 ItemReader 接口创建了一个单独的阅读器类,而不是返回 ListItemReader,现在我只返回 ItemReader。通过实现这一点,我的工作按预期运行。

阅读器类的虚拟代码是:

public class ReaderClass implements ItemReader<Object> {

    final private DataService dataService;

    final private entity entity;

    private List<Object> responseList;

    private int count = 0;

    @Override
    public Product read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
        if(responseList==null){
            responseList = DataService.fetchData(entity);
        }        
        Object obj = null;
        if (count < responseList.size()) {
            obj = responseList.get(count);
            count++;
        }
        return obj;
    }

}
于 2020-08-15T12:50:22.533 回答