2015-03-13 167 views
2

我想跳过一些处理记录。弹簧批处理 - 在处理中跳过记录

我试过的是,我创建了自定义异常并抛出异常,当我想跳过记录,并调用跳过监听器onSkipInProcess method.Its工作正常。

请找到配置。

<batch:chunk reader="masterFileItemReader" writer="masterFileWriter" processor="itemProcessor" commit-interval="5000" skip-limit="100000" > 
    <batch:skippable-exception-classes> 
     <batch:include class="org.springframework.batch.item.file.FlatFileParseException"/> 
     <batch:include class="com.exception.SkipException"/> 
    </batch:skippable-exception-classes> 
    <batch:listeners> 
     <batch:listener ref="recordSkipListener"/> 
</batch:listeners> 

但我想知道是否有任何其他的方式来跳过过程的记录?

问候, 桑卡

+0

是的,我们可以跳过coditional基础上进行记录。请查看此代码片段 – 2015-03-13 13:57:35

+0

您可以随时阅读文档[此处](http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html)和[here](http:/ /docs.spring.io/spring-batch/trunk/reference/html/readersAndWriters.html)。你也可以在这里找到很好的例子(http://www.programcreek.com/java-api-examples/index.php?api=org.springframework.batch.item.ItemProcessor)。 – falsarella 2015-06-15 17:32:10

回答

7

确实有两种方法可以做到这一点,一个像你一样跳跃机制和其他提与返回null这将过滤出项目,而不是写它。这里是documentation link - 6.3.2. Filtering records这里很好地解释了两种方法之间的区别。此外,这blog post解释批量跳过细节和交易。

当你ie分析csv文件,并且你期望每行有5个项目,但是一行保存了6个项目是无效的项目,你可以选择跳过它(通过标记阅读器异常作为可跳过和定义你的策略条件举例)。但是,如果每行包含名称,并且您的用例不写入以字母N开头的项目,并且返回null(筛选项目)可以更好地实施,因为它是有效的项目,但不符合您的业务案例。

请还请注意,如果您返回null数这些项目都将在StepContextgetFilterCount(),如果你使用跳过的方法,他们将在getReadSkipCount()getProcessorSkipCountgetWriteSkipCount尊敬。

+0

感谢@Nenad的详细答案,以及何时使用null和何时使用跳过监听器。 – Shankar 2015-03-15 06:07:18

+0

嗨Nenad,getFilterCount()方法在StepExecution类中,如何通过java获取这个数据?我想在作业中获取跳过的记录数。 – Shankar 2015-03-16 13:08:14

+1

在我的测试中,我正在运行作业并保存该作业的执行,并且当我想验证有多少人被过滤时,使用'jobExecution.getStepExecutions()'这是集合,但是我可以通过它运行并找到通过名称执行的步骤方法'getFilterCount()' – 2015-03-16 14:03:10

1
@Component 
@Scope(value = "step") 
public class XyzItemProcessor implements ItemProcessor<ABCInfo , ABCInfo > { 

@Override 
public ABCInfo process(ABCInfo abcInfo) throws Exception { 

    if (abcInfo.getRecordType().equals("H") || extVoterInfo.getRecordType().equals("T")) 
     return null;////this is how we skip particular record to persist in database 
    else { 
     return abcInfo; 
    } 
} 
} 

返回null将跳过特定的记录在数据库中坚持

+0

谢谢@Bhaji ..我会检查它并让你知道.. – Shankar 2015-03-13 14:38:08

+1

如果你需要定期跳过 - 这是根据标准筛选出的记录,你可以使用返回空值来跳过记录被写入。 onSkipInProcess用于处理期间发生异常并继续处理但想要对错误记录采取某些操作(日志记录,提醒电子邮件) – 2015-03-15 07:17:10

+0

返回'null'不会正好*跳过* ...返回'null'只会*过滤*。 *跳过*用于异常处理。阅读[由Nenad链接的文档](http://stackoverflow.com/a/29048138/1064325)。 – falsarella 2015-06-15 17:25:17

0

当我们在process()方法中返回null时,它会过滤记录并增加过滤器计数。

@Transactional(propagation = Propagation.REQUIRED) 
    @Override 
    public SomeObject process(SomeObject someObject) throws Exception { 
     if (some condition) { 
      return null; 
     } 
} 

如果我们想跳过记录,抛出异常。这将跳过记录并增加processSkipCount。

@Transactional(propagation = Propagation.REQUIRED) 
    @Override 
    public SomeObject process(SomeObject someObject) throws Exception { 
     if (some condition) { 
      throw new Exception("invalid record"); 
     } 
} 

将此异常添加到上下文文件中。

<batch:skippable-exception-classes> 
<batch:include class="java.lang.Exception" /> 
</batch:skippable-exception-classes> 
0

还有一种不写(跳过)东西的方法。例如,假设我们有这样的步骤:

 <batch:step id="createCsvStep"> 
     <batch:tasklet> 
      <batch:chunk reader="jdbcCursorItemReader" processor="processor" writer="compositeWriter" 
         commit-interval="#{jobParameters['commit.interval']}" /> 
     </batch:tasklet> 
     </batch:step> 

     <bean id="compositeWriter" class="org.springframework.batch.item.support.CompositeItemWriter" scope="step"> 
     <property name="delegates"> 
      <list> 
      <ref bean="csvFileItemWriter1"/> 
      <ref bean="csvFileItemWriter2"/> 
      </list> 
     </property> 
     </bean> 

让我们假设第一个作家会写所有的值,但在同一时间,第二个作家会跳过其中的一些。为了实现这一目标,我们可以扩大我们的作家(为前FlatFileItemWriter),并覆盖其写入方法是这样的:

@Override 
public void write(List<? extends T> items) throws Exception { 
    // ... 
    if (itemsPassesCheckingCondition) { 
     super.write(items); 
    } 
}