SpringBatch从入门到实战(五):执行上下文和单步骤重启

奋斗吧
奋斗吧
擅长邻域:未填写

标签: SpringBatch从入门到实战(五):执行上下文和单步骤重启 Python博客 51CTO博客

2023-06-17 18:24:18 196浏览

SpringBatch从入门到实战(五):执行上下文和单步骤重启,JobContext绑定JobExecution执行对象,为Job作业执行提供执行环境(上下文)。


一:执行上下文

SpringBatch从入门到实战(五):执行上下文和单步骤重启_ide

1.1 Job Context 作业上下文

JobContext 绑定 JobExecution 执行对象,为Job作业执行提供执行环境(上下文)。

1.2 Step Context 步骤上下文

StepContext 绑定 StepExecution 执行对象,为Step步骤执行提供执行环境(上下文)。

1.3 ExecutionContext 执行上下文

  • Job ExecutionContext:一次作业运行,所有Step步骤间数据共享。
  • Step ExecutionContext:一次步骤运行,单个Step步骤间(ItemReader/ItemProcessor/ItemWrite组件间)数据共享。

1.4 作业线

  • 作业线Job---JobInstance---JobContext---JobExecution--ExecutionContext
  • 步骤线Step--StepContext --StepExecution--ExecutionContext

1.5 作业上下文API JobSynchronizationManager

JobContext context = JobSynchronizationManager.getContext();
JobExecution jobExecution = context.getJobExecution();
Map<String, Object> jobExecutionContext = context.getJobExecutionContext();
Map<String, Object> jobParameters1 = context.getJobParameters();

1.6 步骤上下文API

StepContext stepContext = chunkContext.getStepContext();
StepExecution stepExecution = stepContext.getStepExecution();
Map<String, Object> stepExecutionContext = stepContext.getStepExecutionContext();
Map<String, Object> jobExecutionContext = stepContext.getJobExecutionContext();
ExecutionContext executionContext = stepExecution.getExecutionContext();
executionContext.put("key", "value");
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext executionContext1 = jobExecution.getExecutionContext();
executionContext1.put("key2", "value2");

1.7上下文案例

@Bean
@StepScope
public Tasklet hellWorldTasklet(@Value("#{jobParameters['timestamp']}") Long timestamp) {
    return new Tasklet() {
        @Override
        public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
            // 步骤上下文
            ExecutionContext stepExeCtx = chunkContext.getStepContext().getStepExecution().getExecutionContext();
            stepExeCtx.put("step-context-key1", "value1");

            // 作业上下文
            ExecutionContext jobExeCtx = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
            jobExeCtx.put("job-context-key1", "value1");
            return RepeatStatus.FINISHED;
        }
    };
}
@Bean
public Tasklet hellWorldTasklet2() {
    return new Tasklet() {
        @Override
        public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
            // 步骤上下文(步骤上下文在步骤里面相当于是局部变量,在其它Step中获取不到)
            ExecutionContext stepExeCtx = chunkContext.getStepContext().getStepExecution().getExecutionContext();
            // null(作业上下文不是用来作业之间共享数据的,而是用来ItemReader、ItemProcessor、ItemWriter之间共享数据的,所以取不到)
            Object stepCtxValue = stepExeCtx.get("step-context-key1");

            // 作业上下文(用来步骤之间共享数据的,所以步骤2能获取到步骤1的数据)
            ExecutionContext jobExeCtx = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
            // value1
            Object JobCtxValue = jobExeCtx.get("job-context-key1");
            return RepeatStatus.FINISHED;
        }
    };
}

BATCH_JOB_EXECUTION_CONTEXT

SpringBatch从入门到实战(五):执行上下文和单步骤重启_springbatch上下文_02


BATCH_STEP_EXECUTION_CONTEXT

SpringBatch从入门到实战(五):执行上下文和单步骤重启_System_03

二:单步骤重启继续运行

该示例是模拟的当一个步骤发生错误时,当修复好错误时,会接上次错误处继续执行,而不是从第一个步骤完重新开始。

@Configuration
public class ErrorJobConfig {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;



    @Bean
    public Job errorJob() {
        return jobBuilderFactory.get("errorJob")
                .start(step1())
                .next(step2())
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        ExecutionContext executionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext();
                        if (!executionContext.containsKey("mock")) {
                            executionContext.put("mock", "value");
                            System.err.println("step1模拟发生异常");
                            throw new RuntimeException("step1模拟发生异常");
                        }
                        System.err.println("step1 execute finish");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }

    @Bean
    public Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        ExecutionContext executionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext();
                        if (!executionContext.containsKey("mock")) {
                            executionContext.put("mock", "value");
                            System.err.println("step2模拟发生异常");
                            throw new RuntimeException("step2模拟发生异常");
                        }
                        System.err.println("step2 execute finish");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
}
@RequestMapping("/start")
public ExitStatus start() throws Exception {
    JobExecution jobExecution = jobLauncher.run(errorJob, new JobParameters());
    return jobExecution.getExitStatus();
}

第一次执行进入step1中的if,抛出异常。BATCH_STEP_EXECUTION_CONTEXT表存储mock键值。

SpringBatch从入门到实战(五):执行上下文和单步骤重启_共享数据_04


SpringBatch从入门到实战(五):执行上下文和单步骤重启_System_05

第二次执行,因为第一次执行已经存储了键值对,所以step1不抛异常,正常执行结束。但是step2会进入if,模拟抛出异常。

SpringBatch从入门到实战(五):执行上下文和单步骤重启_System_06

第三次执行,可以看到step1并没有重复执行,而是跳过成功执行的step1,从错误开始的位置step2开始执行。

SpringBatch从入门到实战(五):执行上下文和单步骤重启_springbatch上下文_07


好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695