Spring Batch 之 skip讲解(九)

来源:互联网 发布:淘宝极速退款卖家拒签 编辑:程序博客网 时间:2024/06/05 16:56

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     @Override13     public boolean shouldSkip(Throwable t, int skipCount)14             throws SkipLimitExceededException {15         // TODO Auto-generated method stub16         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机制的讨论就到这里了,接下来会讨论其他一些高级属性。

 

作者:孤旅者
出处:http://www.cnblogs.com/gulvzhe/
如果本文使您有所收获,请点击右下角的 [推荐]!
如果您对本文有意见或者建议,欢迎留言,哪怕是拍砖(^_^)!
欢迎转载,请注明出处!
感谢您的阅读,请关注后续博客!