首页 文章

spring批处理:跳过后处理器调用两次

提问于
浏览
1

我有一个定义的块,其commit-interval为10,skip-limit为10.处理器类通过应用一些算术运算来操作一个字段 . 在处理器类中,其中一条记录发生异常(例如第6条记录) . 在此之后,再次处理从1到5的记录,跳过第6个,处理7-10个并写入XML(自定义XML编写器类) . 由于处理器处理1-5次记录两次,因此预期的字段值是错误的,因为它被计算两次 . 您能否建议一个解决方案让处理器只处理记录一次,只跳过失败的记录并将处理过的记录写入XML?

使用onSkipInProcess(),onSkipInRead(),onSkipInWrite()实现了一个SkipListener . 但输出仍然相同 .

jobconfig.xml

<batch:job id="job">
    <batch:step id="step">
        <batch:tasklet>
            <batch:chunk reader="itemReader" writer="itemWriter" 
                processor="itemProcessor" commit-interval="10" skip-limit="5" retry-limit="0" >
                <batch:skippable-exception-classes>
                    <batch:include class="java.lang.Exception"/>
                </batch:skippable-exception-classes>
                <batch:listeners>
                    <batch:listener ref="skipListener" />
                </batch:listeners>
            </batch:chunk>
        </batch:tasklet>
    </batch:step>
</batch:job>  
<bean id="itemWriter" class="a.b.XWriter" scope="step"/>
<bean id="skipListener" class="a.b.SkipListener"/>
<bean id="itemProcessor" class="a.b.XProcessor" scope="step"/>
<bean id="itemReader" class="a.b.XReader"/>

ItemReader类:

public class XReader implements ItemReader {
@Autowired
private XRepository classDao;

private List lst = new ArrayList();
private int index= 0;

public Object read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
    if (lst.isEmpty()) {
           lst = classDao.findAll();
    } 
    if (index < lst.size()) {
        return lst.get(index++);
    } else return null;

}
}

ItemProcessor类:

public class XProcessor<T> implements ItemProcessor<T, T> {
public Object process(Object item) throws Exception {
    // logic here
}

ItemWriter类:

public class XWriter <T> implements ItemWriter<T> {
public void write(List<? extends T> items) throws Exception {
    // logic here to write to XML
}}

SkipListener类:

public class SkipListener<T,S> implements org.springframework.batch.core.SkipListener<T, S> {

public void onSkipInProcess(T arg0, Throwable arg1) {
}

public void onSkipInRead(Throwable arg0) {
}

public void onSkipInWrite(S arg0, Throwable arg1) {
}

}

2 回答

  • 0

    在容错步骤中使用 ItemProcessor 时,它们应该是幂等的,因为存在多次调用它们的风险(如示例所示) . 您可以在此处的文档的第6.3.3节中阅读更多相关信息:http://docs.spring.io/spring-batch/reference/html/readersAndWriters.html

  • 2

    你需要有一个像下面这样的监听器实现 . 每当发生一些异常时,它会调用相应的方法,如果需要,您可以处理,否则只需将方法保留为空 . 所以它不会失败的工作 .

    它也不会两次调用处理器 .

    xml configuration:

    <batch:listeners>
                        <batch:listener ref="recordSkipListener"/>
                      </batch:listeners>
    

    Listener class:

    public class RecordSkipListener implements SkipListener<Model> {
    
    
    
        @Override
        public void onSkipInRead(Throwable t) {
    
    
        }
    
        @Override
        public void onSkipInWrite(Model item, Throwable t) {
    
        }
    
        @Override
        public void onSkipInProcess(Model item, Throwable t) {
    
    
        }
    }
    

相关问题