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

news2024/12/23 12:05:23

一:执行上下文

在这里插入图片描述

1.1 JobContext 作业上下文

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

1.2 StepContext 步骤上下文

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
在这里插入图片描述
BATCH_STEP_EXECUTION_CONTEXT
在这里插入图片描述

二:错误处继续执行

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

@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键值。
在这里插入图片描述
在这里插入图片描述

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

第三次执行,可以看到step1并没有重复执行,而是跳过成功执行的step1,从错误开始的位置step2开始执行。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/652745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ansible playbook ----- 剧本

playbooks 本身由以下各部分组成 &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0c;即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 &#xff08;2&#xff09;Variables&#xff1a;变量 &#xff08;3&#xff09;Templates&#xff1a;模…

Ubuntu 20.04 LTS 安装教程

Ubuntu 20.04 LTS 以及必要软件的安装教程 1、Ubuntu 系统下载2、制作U盘安装盘3、安装Ubuntu系统4、必要软件安装4.1、调整系统时间4.2、安装搜狗中文输入法4.3、anaconda 安装4.4、安装 terminator4.4、安装 nvidia 驱动 1、Ubuntu 系统下载 官方桌面版下载&#xff1a;https…

电力监控系统软件的设计与功能介绍

安科瑞虞佳豪 风吹麦浪&#xff0c;炎夏将至。随着气温节节攀升&#xff0c;社会用电需求越来越大&#xff0c;给电网安全和电力供应带来挑战。国网诸城市供电公司扛牢电力保供责任&#xff0c;迎难而上&#xff0c;筑牢强电网、保安全、防大汛“三部曲”&#xff0c;全力保障…

数据库优化可以从哪些维度入手?(建议收藏)

当有人问你如何对数据库进行优化时&#xff0c;很多人第一反应想到的就是SQL优化&#xff0c;如何创建索引&#xff0c;如何改写SQL&#xff0c;他们把数据库优化与SQL优化划上了等号。 当然这不能算是完全错误的回答&#xff0c;只不过思考的角度稍微片面了些&#xff0c;太“…

还在争论WPS、Office哪个更好用?3款云办公平台深度评测!

随着当下智能化产业发展&#xff0c;办公系统也逐渐升级。像答主所在公司就已经使用了简道云办公平台&#xff0c;真正实现无纸化办公&#xff0c;极大地提升了工作效率。什么是云办公平台&#xff1b;相较于传统办公平台&#xff0c;云办公平台又哪些独特的优势呢&#xff0c;…

Vue-props配置

props配置 像el&#xff0c;data&#xff0c;watch&#xff0c;methods…都是vue的配置项&#xff0c;props也是一个配置项 props主要用来实现组件复用&#xff0c;并且动态绑定数据,它有3种使用方式&#xff0c;下面一一说明 通过案例进行分析使用props配置学习如何使用以及…

手写STM32IIC协议

本文使用正点原子战舰v4开发板&#xff0c;用软件模拟iic协议而非使用硬件iic。 STEP1&#xff1a; 定义、声明引脚功能。我们用PB6、PB7模拟IIC的SCL、SDA。另外定义IO方向 #define IIC_SCL PBout(6) //SCL #define IIC_SDA PBout(7) //SDA #define READ_SDA PBin(7…

chatgpt赋能python:Python绘制彩色蟒蛇-让你的绘图更加有趣

Python绘制彩色蟒蛇-让你的绘图更加有趣 如果你是一名喜欢使用Python语言进行绘图的程序员&#xff0c;你可能会遇到无聊的绘图任务&#xff0c;这时候你就需要一个有趣的绘图项目来激发你的创造力。在本文中&#xff0c;我将介绍如何使用Python代码绘制一条彩色的蟒蛇&#x…

Unity与Android交互(3)——需要了解的Andorid基础知识

【前言】 在上一篇文章中只是说了如何实现unity和android交互的问题&#xff0c;要了解其中的原理还必须要先了解一些Android的基础知识&#xff0c;了解后也能搞清楚如何接入SDK或者写Native插件。 &#xff08;以下只是简要介绍&#xff0c;详细的内容需要自己去看链接&…

Oracle 查询优化改写(第四章)

第四章 插入、更新与删除 1.阻止对某几列插入 2. 用with check option 限制数据录入 当约束条件比较简单时&#xff0c;可以直接加在表中&#xff0c;如工资必须大于0&#xff1a; alter table emp add constraint ch_sal check(sal>0) 但有些复杂或特殊的约束条件是不能…

MySQL高级篇-索引分析与优化、数据库锁机制与主从复制

MySQL高级 基于MySQL版本5.5 MySQL的架构介绍 MySQL简介 概述 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB公司开发&#xff0c;目前属于Oracle公司。 MySQL是一种关联数据库管理系统&#xff0c;将数据保存在不同的表中&#xff0c;而不是将所有的数据放在…

化工企业针对消防安全的具体防火对策介绍 安科瑞 许敏

摘要&#xff1a;我们国家对化工企业的消防安全问题是非常关注的&#xff0c;而且化工企业当中生产的产品都是具有危险性的&#xff0c;极容易发生爆炸等危险事故&#xff0c;所以化工企业出现泄漏就会产生严重后果。下面这篇文章我们就对化工企业的消防安全问题进行具体的探讨…

机器人视觉梳理(下)

原创 | 文 BFT机器人 03 机器人3D视觉应用案例 1.波士顿动力Atlas Atlas 使用 TOF 深度相机以每秒 15 帧的速度生成环境的点云&#xff0c;点云是测距的大规模集合。Atlas 的感知软件使用一种名为多平面分割的算法从点云中提取平面。多平面分割算法的输入馈入到一个映射系统…

Linux运维监控学习笔记3

通过Zabbix-agent监控远程主机 1、在agent1上安装abbix-agent包&#xff1a; yum install -y zabbix-agent 2、配置zabbix-agent端的配置文件&#xff0c;启动服务器并进行开机自启动配置&#xff1a; vim /etc/zabbix/zabbix-agentd.confServer192.168.17.11 # 被动模式s…

【数据分析】如何使用docker部署程序并移植(算法、接口)

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、Docker的基本使用1.安装Docker2.列出本地镜像3.获取镜像,创建本地ubuntu:13.10镜像4.查找镜像5.删除本地镜像6.创建自定义镜像7.镜像…

数学专业毕业生做高性能计算工程师合适吗?

一般人看到数学专业都会很奇怪&#xff0c;学数学有什么用呢&#xff0c;能就业吗&#xff1f;其实不然。像数学、应用数学、物理、地球物理、化工等传统工科专业&#xff0c;在当今形式多变的就业环境下&#xff0c;反而是通用的香饽饽。 拿数学专业来举例&#xff0c;就有有许…

MATLAB | 如何使用MATLAB获取顶刊cell全部绘图(附带近3年全部图像)

众所周知&#xff0c;学习科研绘图、配色最好的办法就是去观摩顶级期刊上的作图&#xff0c;本来想着收集各个顶级期刊绘图提供给大家&#xff0c;但是每年的图像加起来大约3-5G&#xff0c;撑死也就能提供三四年的图像&#xff0c;再多内存可能不太够了&#xff0c;于是我写了…

【python】pandas-DataFrame类型数据重命名列表头

目录 0.环境 1.将DataFrame类型数据某一列重命名 0.环境 windows jupyter notebook python 使用场景&#xff1a; 在处理数据对齐的问题时&#xff0c;两个表格的对齐列名不相同&#xff08;一个数据集是DataFrame类型&#xff0c;一个数据集是geopandas类型&#xff09;&…

加速金融营销科技价值发现,神策数据双引擎赋能数字化客户经营

6 月 9 日&#xff0c;「开放融合&#xff0c;引领营销 5.0 新纪元——暨 2023 年金融营销科技价值发现论坛」在中国杭州成功举办。 神策数据创始人 & CEO 桑文锋发表了《双引擎赋能数字化客户经营》的主题演讲&#xff0c;并与数十位来自银行、证券、保险、互联网金融等领…

基于Eclipse+Java+Swing+Mysql实现进销存管理系统

基于EclipseJavaSwingMysql实现进销存管理系统 一、系统介绍二、功能展示1.登陆2.商品列表3.购买清单4.个人中心5.商品采购6、采购记录7、商品预警 三、数据库四、其它1.其他系统实现五.获取源码 一、系统介绍 用户&#xff1a;商品列表、购买清单、个人中心 管理员&#xff1…