• Spring Batch 之 skip讲解(九)


          前面的文章跟大家一起讨论了Spring Batch的概念,处理流程,以及SpringBatch处理文件、DB的一些简单实例。接下来的讨论,主要是关于Spring Batch的一些高级应用处理和实际开发中需要注意的一些问题。

          今天主要和大家讨论SpringBatch关于skip容错机制的一些处理。

          一、skip的介绍

          在实际的项目开发中,我们常常要将几十万甚至上百万的数据从文件导入到DB中,如果其中某条数据导入时发生例外,我们并不想整个Job以失败而结束,而是希望能将错误的数据经过处理后保存起来,其余正确的数据继续做导入处理。如果遇到这样的场景,SpringBatch的skip机制就可以派上用场了。顾名思义,skip的作用就是跳过某些数据(例如错误数据)。 

          二、配置skip信息

          配置skip的示例代码如下:

     1 <job id="csvJob">
    2 <step id="csvStep">
    3 <tasklet transaction-manager="transactionManager">
    4 <chunk reader="itemReaders" writer="itemWriter" processor="itemProcessor"
    5 commit-interval="1" skip-limit="1000">
    6 <skippable-exception-classes>
    7 <include class="org.springframework.batch.item.file.FlatFileParseException" />
    8 </skippable-exception-classes>
    9 </chunk>
    10 </tasklet>
    11 </step>
    12 </job>

          代码第5行chunk的skip-limit属性是指允许跳过记录的行数,6-8行是指允许发生的例外,也就是说在发生FlatFileParseException(及其子类)的时候,job是不会被终止的,而是跳过当前的记录,去执行下面那条记录。 上面的代码也会有另外一个问题,就是发生FlatFileParseException以外例外的时候,Job也会失败。这也满足不了我们上面说的那种场景,当然,6-8行还有另外一种配置方式,如下:

    1 <skippable-exception-classes>
    2   <include class="java.lang.Exception"/>
    3 <exclude class="java.io.FileNotFoundException"/>
    4 </skippable-exception-classes>

          include是允许跳过的错,exclude是不允许跳过的错。如果像上诉代码那样配置的话,所有Exception及其子类(FileNotFoundException除外)发生时,Job都不会被终止;但是当FileNotFoundException发生时,虽然它也是Exception的子类,但Job会被终止,因为FileNotFoundException属于exclude属性的class。

          三、skip深入讲解

          是谁在决定当前的记录跳过与否呢?其实,当Reader、Processor和Writer抛出例外的时候,SpringBatch会调用skip机制,来判断当前例外发生时,正在被处理的记录是否被跳过。当在上面的代码中配置skippable-exception-classes属性的时候,SpringBatch会默认的调用LimitCheckingItemSkipPolicy类。如果简单的配置skip-limit和skippable-exception-classes不能满足需求时,也可以定义自己的skip策略。代码如下:

     1 package com.wanggc.springbatch.sample;
    2
    3 import org.springframework.batch.core.step.skip.SkipLimitExceededException;
    4 import org.springframework.batch.core.step.skip.SkipPolicy;
    5
    6 /**
    7 * 自定义Skip策略类。
    8 * @author Wanggc
    9 */
    10 public class MySkipPolicy implements SkipPolicy {
    11
    12 @Override
    13 public boolean shouldSkip(Throwable t, int skipCount)
    14 throws SkipLimitExceededException {
    15 // TODO Auto-generated method stub
    16 return false;
    17 }
    18 }

          如示例代码所示,要实现SkipPolicy接口,在shouldSkip方法中定义自己的skip策略。返回false时,说明当前例外不能被跳过,否则可以被跳过。当然,定义了自己的skip策略还不够,还要告诉框架要使用自己定义的skip策略,而不是框架默认的。这就需要添加chunk的另外一个属性skip-policy。代码如下:

     1 <job id="csvJob">
    2 <step id="csvStep">
    3 <tasklet transaction-manager="transactionManager">
    4 <chunk reader="itemReaders" writer="itemWriter" processor="itemProcessor"
    5 commit-interval="1" skip-limit="1000" skip-policy="mySkipPolicy">
    6 <skippable-exception-classes>
    7 <include
    8 class="org.springframework.batch.item.file.FlatFileParseException" />
    9 </skippable-exception-classes>
    10 </chunk>
    11 </tasklet>
    12 </step>
    13 </job>
    14 <bean:bean id="mySkipPolicy" class="com.wanggc.springbatch.sample.MySkipPolicy"/>

          添加了skip-policy属性后,skip-limit和skippable-exception-classes默认策略将不再起作用。当然,可以将其删除,示例中属于垃圾代码。

          当Reader、Processor和Writer抛出例外的时候,SpringBatch处理skip策略的方式是不同的。当Reader发生可以被skip的例外时,SpringBatch会接着去读下面一条记录,并不会回滚事务。当Processor发生可以被skip的例外时,SpringBatch会回滚当前chunk的事务,并将除了引发例外以外的数据传给Writer。当Writer发生可以被skip的例外的时,SpringBatch首先回滚事务,因为传给Writer的是一个list,所以Writer不知道是list中那条记录造成了例外的发生。Writer会将list拆开,一条条的处理,正确的数据提交,错误的数据回滚。

          对SpringBatch的skip机制的讨论就到这里了,接下来会讨论其他一些高级属性。

    作者:孤旅者
    如果您对本文有意见或者建议,欢迎留言,哪怕是拍砖(^_^)!
    欢迎转载,请注明出处!
    感谢您的阅读,请关注后续博客!
    共享视频教程请访问:JAVA 高级软件工程师视频
  • 相关阅读:
    常用Linux命令
    KDevolop使用小技巧
    微软在5/10/2006发布新版的LINQ Preview (May 2006).msi 无为而为
    盼望已久的Office Live Beta 已经发布,大家可以去尝尝鲜 无为而为
    需求工程:TFS MSF模版中UI Flow model的应用 无为而为
    Visual Studio 2005 Team Foundation Server 试用版及中文说明文件下载,中文版可能在2006年5月15日发布 无为而为
    让我们努力从“不可救药的乐观主义者”华尔街知名投资人约翰。多尔那里学点东西(永远放弃尝试改变这个世界) 无为而为
    Visual Studio 2005 开发Office(Word/Excel)项目的若干资源和示例 无为而为
    IT人看《国富论》系列:第一篇之第十章:论工资与利润随劳动与资本用途的不同而不同,分析分析IT界薪水起伏的原因 无为而为
    非正常状态,彻底删除Exchange服务器 无为而为
  • 原文地址:https://www.cnblogs.com/gulvzhe/p/2309690.html
Copyright © 2020-2023  润新知