首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring Batch 批处理(7) - 异常处理及容错机制

Spring Batch 批处理(7) - 异常处理及容错机制

作者头像
chenchenchen
发布于 2020-05-26 09:17:38
发布于 2020-05-26 09:17:38
1.7K00
代码可运行
举报
文章被收录于专栏:chenchenchenchenchenchen
运行总次数:0
代码可运行

异常处理及重启机制

1.对于chunk类型的Step,spring batch为我们提供了用于管理它的状态

2.状态的管理是通过ItemStream接口来实现的

3.ItemStream接口:

(1)open():每一次step执行会调用

(2)Update():每一个chunk去执行都会调用

(3)Close():所有的chunk执行完毕会调用

![file](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9ncmFwaC5iYWlkdS5jb20vcmVzb3VyY2UvMjIyODc5Y2ZkODQ2YjExZDhlM2VlMDE1ODMyMjgzMzAucG5n?x-oss-process=image/format,png)

构造例子

准备个cvs文件,在第33条数据,添加一条错误名字信息 ;当读取到这条数据时,抛出异常终止程序。

ItemReader测试代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component("restartDemoReader")
public class RestartDemoReader implements ItemStreamReader<Customer> {
 
    // 记录当前读取的行数
    private Long curLine = 0L;
    // 重启状态初始值
    private boolean restart = false;
 
    private FlatFileItemReader<Customer> reader = new FlatFileItemReader<>();
 
    // 持久化信息到数据库
    private ExecutionContext executionContext;
    RestartDemoReader
    public () {
        
        reader.setResource(new ClassPathResource("restartDemo.csv"));
 
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setNames(new String[]{"id", "firstName", "lastName", "birthdate"});
 
        DefaultLineMapper<Customer> lineMapper = new DefaultLineMapper<>();
        lineMapper.setLineTokenizer(tokenizer);
        lineMapper.setFieldSetMapper((fieldSet -> {
            return Customer.builder().id(fieldSet.readLong("id"))
                    .firstName(fieldSet.readString("firstName"))
                    .lastName(fieldSet.readString("lastName"))
                    .birthdate(fieldSet.readString("birthdate"))
                    .build();
        }));
        lineMapper.afterPropertiesSet();
 
        reader.setLineMapper(lineMapper);
    }
 
    @Override
    public Customer read() throws Exception, UnexpectedInputException, ParseException,
            NonTransientResourceException {
 
        Customer customer = null;
 
        this.curLine++;
        //如果是重启,则从上一步读取的行数继续往下执行
        if (restart) {
            reader.setLinesToSkip(this.curLine.intValue()-1);
            restart = false;
            System.out.println("Start reading from line: " + this.curLine);
        }
 
        reader.open(this.executionContext);
 
        customer = reader.read();
        //当匹配到wrongName时,显示抛出异常,终止程序
        if (customer != null) {
            if (customer.getFirstName().equals("wrongName"))
                throw new RuntimeException("Something wrong. Customer id: " + customer.getId());
        } else {
            curLine--;
        }
        return customer;
    }
 
    /**
     * 判断是否是重启job
     * @param executionContext
     * @throws ItemStreamException
     */
    @Override
    public void open(ExecutionContext executionContext) throws ItemStreamException {
        this.executionContext = executionContext;
				// 如果是重启job,从数据库读取重启的行数,从重启行数开始重新执行
        if (executionContext.containsKey("curLine")) {
            this.curLine = executionContext.getLong("curLine");
            this.restart = true;
        }
				// 如果不是重启job,初始化行数,从第一行开始执行
				else {
            this.curLine = 0L;
            executionContext.put("curLine", this.curLine.intValue());
        }
 
    }
 
    @Override
    public void update(ExecutionContext executionContext) throws ItemStreamException {
		    // 每执行完一个批次chunk,打印当前行数
        System.out.println("update curLine: " + this.curLine);
        executionContext.put("curLine", this.curLine);
 
    }
 
    @Override
    public void close() throws ItemStreamException {
 
    }
}

Job配置

以10条记录为一个批次,进行读取

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class RestartDemoJobConfiguration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
 
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
 
    @Autowired
    @Qualifier("flatFileDemoWriter")
    private ItemWriter<? super Customer> flatFileDemoWriter;
 
    @Autowired
    @Qualifier("restartDemoReader")
    private ItemReader<Customer> restartDemoReader;
 
    @Bean
    public Job restartDemoJob(){
        return jobBuilderFactory.get("restartDemoJob")
                .start(restartDemoStep())
                .build();
 
    }
 
    @Bean
    public Step restartDemoStep() {
        return stepBuilderFactory.get("restartDemoStep")
                .<Customer,Customer>chunk(10)
                .reader(restartDemoReader)
                .writer(flatFileDemoWriter)
                .build();
    }
}

当第一次执行时,程序在33行抛出异常异常,curline值是30;

这时,可以查询数据库 batch_step_excution表,发现curline值已经以 键值对形式,持久化进数据库(上文以10条数据为一个批次;故33条数据异常时,curline值为30)

接下来,更新wrongName,再次执行程序;

程序会执行open方法,判断数据库step中map是否存在curline,如果存在,则是重跑,即读取curline,从该批次开始往下继续执行;

容错机制

Spring batch的容错机制是一种与事务机制相结合的机制,它主要包括有3种操作:

  • restart
  • restart是针对job来使用,是重启job的一个操作。默认情况下,当任务出现异常时,SpringBatch会结束任务,当使用相同参数重启任务时,SpringBatch会去执行未执行的剩余任务
  • retry
  • retry是对job的某一step而言,处理一条数据item的时候发现有异常,则重试一次该数据item的step的操作。
  • skip
  • skip是对job的某一个step而言,处理一条数据item的时候发现有异常,则跳过该数据item的step的操作。

restart示例代码如下,当第一次执行的时候,上下文中没有该字段,抛出异常,第二次执行,已存在该字段,执行成功

retry、skip示例如下,更改一下之前step的配置,参考代码如下: ``` @Bean public Step stepForTranscation(StepBuilderFactory stepBuilderFactory, @Qualifier("stepForTranscationReader")ListItemReader reader, @Qualifier("stepForTranscationProcessor")ItemProcessor

}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<br/>


这里设置了允许重试的次数为3次,允许跳过的数据最多为1条,如果job失败了,运行重跑次数最多为3次。

<br/>
在skip后面配置跳过错误的监听器SkipListener

public class MySkipListener implements SkipListener<String, String>{ // 发生读操作跳过错误时,需要执行的监听 public void onSkipInRead(Throwable t){ }

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 发生写操作跳过错误时,需要执行的监听
public void onSkipInWrite(String item, Throwable t){
}

// 处理数据时跳过错误时,需要执行的监听
public void onSkipInProcess (String item, Throwable t){
	System.out.println(item + "occur exception" + t);
}

}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<br/>


重新运行程序,可以得到新的结果:

![file](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9ncmFwaC5iYWlkdS5jb20vcmVzb3VyY2UvMjIyNzJjYzk4ZTk5ZTk4Nzg1NWU3MDE1ODM0MjUzNDUucG5n?x-oss-process=image/format,png)

<br/>

这次可以看到,12条数据中总共有11条数据进入到数据库,而过长的008008008008数据,则因为设置了skip,所以容错机制允许它不进入数据库,这次的Spring batch最终没有因为回滚而中断。

<br/>
查阅一下Spring batch的持久化数据表:

![file](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9ncmFwaC5iYWlkdS5jb20vcmVzb3VyY2UvMjIyNjE5YTg3M2VjNGNkNDE0Y2U1MDE1ODM0MjUzNTUucG5n?x-oss-process=image/format,png)

可以看出,的确是有一条数据被跳过了,但因为是我们允许它跳过的,所以整个job顺利完成,即COMPLETED。



参考:

https://blog.csdn.net/chihe9907/article/details/100601523
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/03/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
SpringBoot 配置 HTTPS 安全证书的两种方案
来源:https://blog.csdn.net/lhc_makefunny 文章目录 使用JDK自带的工具生成证书 使用FreeSSL提供的证书 使用JDK自带的工具生成证书 1.确保安装了JDK并正确配置了环境变量; 2.进入你的JAVA_HOME目录中的bin目录; 3.在这个目录下执行 //  keytool -genkey -alias (别名) -dname "CN=(姓名),OU=(组织单位名称),O=(组织名称),L=(城市名称),ST=(省),C=(国家)" -storetype (密钥仓
程序猿DD
2022/09/22
1.2K0
SpringBoot 配置 HTTPS 安全证书的两种方案
springboot(22)同时支持http和https访问
关于spring boot同时支持http和https访问,在spring boot官网73.9已经有说明文档了,同样在github上也有官网的例子。 在这里,我向大家讲述一下,我是怎么实现的。 keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 1.-storetype 指定密钥仓库类型 2.-keyalg 生证书的算法名称,RS
IT架构圈
2018/06/01
4K0
在Spring Boot中使用HTTPS
在本文中,我们将学习在Spring Boot中使用自签名证书配置SSL(HTTPS),并且要在嵌入式Tomcat上启用Spring Boot应用程序的SSL,我们需要学习以下步骤: 1.创建SSL证书:生成自签名证书,或者使用由受信任的证书颁发机构(CA)颁发的证书。 2.在Spring Boot中启用HTTPS:这可以通过Spring Boot 项目中的一些简单配置来完成。 3. 将HTTP重定向到HTTPS :在某些情况下,最好也能从HTTP访问你的应用,将所有HTTP流量重定向到HTTPS端
lyb-geek
2018/08/16
2.9K0
SpringBoot两种方式配置 HTTPS 安全证书
1:确保安装了JDK并正确配置了环境变量; 2:进入你的JAVA_HOME目录中的bin目录; 3:在这个目录下执行
高大北
2022/06/14
1.5K0
Springboot模拟https安全访问(使用Java提供的keytool命令生成证书)
1、SpringBoot启动时默认采用http进行通信协议定义,但是为了访问安全性,我们有时候会选择使用https进行访问。正常来讲,https的访问是需要证书的,并且为了保证这个证书的安全,一定要在项目中使用CA进行认证,需要收费的哦,证书真是一个挣钱的生意。这里只是利用Java提供的keytool命令实现证书的生成。
别先生
2020/11/24
8790
Springboot模拟https安全访问(使用Java提供的keytool命令生成证书)
为我们的Web添加HTTPS支持
按:最近公众号文章主要是整理一些老文章,以个人CSDN上的博客为主,也会穿插一些新的技术点。 ---- 上篇博客使用Spring Boot开发Web项目我们简单介绍了使用如何使用Spring Boot创建一个使用了Thymeleaf模板引擎的Web项目,当然这还远远不够。今天我们再来看看如何给我们的Web项目添加https支持。在阅读本篇博客之前,强烈建议先读使用Spring Boot开发Web项目这篇博客,否则可能会有对Spring Boot不太了解的小伙伴看的云里雾里。 什么是https 要说https
江南一点雨
2018/04/02
2.1K0
为我们的Web添加HTTPS支持
Springboot 系列(十四)迅速启用 HTTPS 加密你的网站
正常情况下 HTTPS 证书需要从证书授权中心获得,这样获得的证书才具有公信力,也会被各种浏览器客户端所认可。常见的证书品牌如 Symantec,GeoTrustm,TrustAsia,Symantec 等。不过在 Springboot 的 HTTPS 实验中就没有必要去申请了,我们可以使用 Java 自带的 keytool 生成 HTTPS 证书。
未读代码
2019/11/04
8821
Spring Boot第七章-Spring Boot Web配置-Tomcat配置
直接在application配置文件中配置即可,servlet容器配置以server为前缀,而tomcat的特有配置以server.tomcat为前缀,至于有哪些参数可以在实际工作中需要了再找。配置例子:
全栈程序员站长
2021/05/19
1.1K0
SpringBoot项目安装SSL协议
概述 这个需求是我目前做的项目被网安评测的时候,一个漏洞的解决方案。使用SpringBoot内置Tomcat启动应用程序为http协议访问,应网安需求修改为https://协议访问项目,网络搜索出了两种解决方案,一种为使用JDK本地程序生成SSL证书,部署到SpringBoot项目上,一种使用云服务商提供的SSL证书,但是云服务器商提供证书需要域名校验,无法应用在localhost项目上面,故而选择第一种使用JDK本地生成SSL证书,如果浏览器弹框显示不安全就将证书部署在浏览器上面 开发环境 IDEA:I
框架师
2021/08/05
1.4K0
springboot监控&springboot配置https
springboot自带actuator监控,开启配置后,访问相关链接就可以返回服务运行相关信息,使用方法如下: 1、pom.xml:
贪挽懒月
2020/08/13
1.3K0
springboot监控&springboot配置https
重学SpringBoot系列之嵌入式容器的配置与应用
在Spring Boot项目中,可以支持Tomcat、Jetty、Undertow的Web应用服务容器。当我们添加了spring-boot-starter-web依赖后,默认会使用Tomcat作为嵌入式Web容器,不需要我们单独部署,将web应用打成jar包即可运行。
大忽悠爱学习
2021/12/07
1.8K0
重学SpringBoot系列之嵌入式容器的配置与应用
秒懂HTTPS接口(实现篇)
创建一个接口PersonRepository,后续的控制器直接调用该接口继承自JpaRepository的方法,来实现和数据库交互
高楼Zee
2019/07/17
2.1K0
秒懂HTTPS接口(实现篇)
SpringBoot配置HTTPS及开发调试
在实际开发过程中,如果后端需要启用https访问,通常项目启动后配置nginx代理再配置https,前端调用时高版本的chrome还会因为证书未信任导致调用失败,通过摸索整理一套开发调试下的https方案,特此分享
code2roc
2024/04/30
1670
SpringBoot配置HTTPS及开发调试
Spring Boot配置ssl证书启用HTTPS协议
SSL协议分为两层:SSL记录协议,它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL握手协议,它建立在SSL记录协议之上。用于在实际数据传输开始前,通信双方进行身份认证、协商加密算法、交换加密密钥等。
故久
2019/09/29
5.4K0
Spring Boot配置ssl证书启用HTTPS协议
SpringBoot之Https
前言:Springboot因为是内置一个tomcat,在需要安全性的情况下需要配置ssl访问。
王念博客
2019/07/25
1K0
Spring Boot-4.servlet容器配置
Spring Boot默认Tomcat为Servlet容器,以Tomcat为例进行说明,Tomcat,Jetty,Undertow都是通用的。
悠扬前奏
2019/05/30
8100
spring boot支持https请求(建议收藏)
众所周知,http是不安全的协议,那么要使服务器支持https,该如何在spring项目中配置呢?
VIBE
2023/02/02
3.4K0
spring boot支持https请求(建议收藏)
springboot(21)容器整合
SpringBoot可以嵌入容器从而更好实现微服务,默认支持Tomcat和Jetty的嵌入,只需要在POM文件中导入相应的依赖即可。在有些场景下,我们需要将服务发布到项目早已搭建好的WEB容器中。常见
IT架构圈
2018/06/01
8210
SpringBoot配置Https
可以直接通过域名申请; 也可以使用自签证书(自签证书创建可以看我的另一篇文章:[使用KeyStore生成证书]) ​
十玖八柒
2022/08/01
1.3K0
SpringBoot配置Https
Spring Boot启用HTTPS
默认情况下,Spring Boot应用程序在应用程序启动时使用HTTP的8080端口。可按照以下步骤,在Spring Boot应用程序中配置HTTPS和端口443 -
黑洞代码
2021/09/03
9740
相关推荐
SpringBoot 配置 HTTPS 安全证书的两种方案
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档