Spring 批处理 - 过程中跳过记录

Spring Batch - Skip Record On Process

我想跳过过程中的一些记录。

我试过的是,我创建了自定义异常并在我想跳过记录时抛出异常,它调用 Skip 侦听器 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>

但是我想知道有没有其他方法可以跳过进程中的记录?

此致, 香卡

@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;
    }
}
}

Return null 将跳过要保存在数据库中的特定记录

确实有两种方法可以做到这一点,一种像你提到的使用跳过机制,另一种使用 returning null 将过滤掉项目而不是写入它。这里是documentation link - 6.3.2. Filtering records where it is nicely explained what is difference between two approaches. Also this blog post详细解释跳过和批量交易。

当您即解析 csv 文件并且您期望每行 5 个项目但一行包含 6 个无效项目时,您可以选择退出以跳过它(通过将 reader 异常标记为可跳过并定义您举的例子中的政策条件)。但是,如果每一行都包含名称,并且您的用例是不要编写以字母 N 开头的项目,那么最好使用 returning null (过滤项目)来实现,因为它是有效的项目但是不是根据您的业务案例。

另请注意,如果您 return null 这些项目的数量将在 StepContextgetFilterCount() 中,如果您使用跳过方法,它们将在 [ =16=、getProcessorSkipCountgetWriteSkipCount 恭敬。

当我们在 process() 方法中 return 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>

还有另一种不写(跳过)内容的方法。例如,假设我们有这一步:

        <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);
    }
}