Spring batch Spring批处理示例,用于从表中读取单个作业,然后按类型和并行进程拆分结果

Spring batch Spring批处理示例,用于从表中读取单个作业,然后按类型和并行进程拆分结果,spring-batch,Spring Batch,每个并行步骤将创建一个文件,如果所有步骤都成功,则这些文件将一起移动到输出文件夹。如果这些步骤中的任何一个失败,那么所有文件都不会进入输出文件夹,整个作业都会失败。非常感谢您对batch noob的帮助/代码示例 从表中读取数据,然后按类型和并行处理拆分结果 您可以使用分区步骤按类型对数据进行分区。分区将被并行处理,每个分区创建一个文件。然后在分区步骤之后添加步骤,以便在任何分区失败时清理文件。下面是一个您可以尝试的快速示例: import java.io.IOException; import

每个并行步骤将创建一个文件,如果所有步骤都成功,则这些文件将一起移动到输出文件夹。如果这些步骤中的任何一个失败,那么所有文件都不会进入输出文件夹,整个作业都会失败。非常感谢您对batch noob的帮助/代码示例

从表中读取数据,然后按类型和并行处理拆分结果

您可以使用分区步骤按类型对数据进行分区。分区将被并行处理,每个分区创建一个文件。然后在分区步骤之后添加步骤,以便在任何分区失败时清理文件。下面是一个您可以尝试的快速示例:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.partition.support.Partitioner;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

@Configuration
@EnableBatchProcessing
public class PartitionJobSample {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public Step step1() {

        return steps.get("step1")
                .partitioner(workerStep().getName(), partitioner())
                .step(workerStep())
                .gridSize(3)
                .taskExecutor(taskExecutor())
                .build();
    }

    @Bean
    public SimpleAsyncTaskExecutor taskExecutor() {
        return new SimpleAsyncTaskExecutor();
    }

    @Bean
    public Partitioner partitioner() {
        return gridSize -> {
            Map<String, ExecutionContext> map = new HashMap<>(gridSize);
            for (int i = 0; i < gridSize; i++) {
                ExecutionContext executionContext = new ExecutionContext();
                executionContext.put("data", "data" + i);
                String key = "partition" + i;
                map.put(key, executionContext);
            }
            return map;
        };
    }

    @Bean
    public Step workerStep() {
        return steps.get("workerStep")
                .tasklet(getTasklet(null))
                .build();
    }

    @Bean
    @StepScope
    public Tasklet getTasklet(@Value("#{stepExecutionContext['data']}") String partitionData) {
        return (contribution, chunkContext) -> {
            if (partitionData.equals("data2")) {
                throw new Exception("Boom!");
            }
            System.out.println(Thread.currentThread().getName() + " processing partitionData = " + partitionData);
            Files.createFile(Paths.get(partitionData + ".txt"));
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Step moveFilesStep() {
        return steps.get("moveFilesStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("moveFilesStep");
                    // add code to move files where needed
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step cleanupFilesStep() {
        return steps.get("cleanupFilesStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("cleaning up..");
                    deleteFiles();
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Job job() {
        return jobs.get("job")
                    .flow(step1()).on("FAILED").to(cleanupFilesStep())
                    .from(step1()).on("*").to(moveFilesStep())
                    .from(moveFilesStep()).on("*").end()
                    .from(cleanupFilesStep()).on("*").fail()
                    .build()
                .build();
    }

    public static void main(String[] args) throws Exception {
        deleteFiles();
        ApplicationContext context = new AnnotationConfigApplicationContext(PartitionJobSample.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

    private static void deleteFiles() throws IOException {
        for (int i = 0; i <= 2; i++) {
            Files.deleteIfExists(Paths.get("data" + i + ".txt"));
        }
    }

}
在这种情况下,将触发清除文件步骤,并删除所有文件

希望这有帮助

    @Bean
    @StepScope
    public Tasklet getTasklet(@Value("#{stepExecutionContext['data']}") String partitionData) {
        return (contribution, chunkContext) -> {
            if (partitionData.equals("data2")) {
                throw new Exception("Boom!");
            }
            System.out.println(Thread.currentThread().getName() + " processing partitionData = " + partitionData);
            Files.createFile(Paths.get(partitionData + ".txt"));
            return RepeatStatus.FINISHED;
        };
    }