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

Spring batch spring批处理:跳过后调用两次处理器,spring-batch,Spring Batch,我定义了一个块,提交间隔为10,跳过限制为10。处理器类通过应用一些算术运算来操作字段。其中一条记录(例如第6条记录)发生处理器类内异常。在此之后,再次处理1到5条记录,跳过第6条记录,处理7到10条记录并将其写入XML(自定义XML编写器类)。由于处理器处理1-5条记录两次,因此预期字段值计算两次是错误的。您能否建议一种解决方案,让处理器只处理一次记录,只跳过失败的记录,并将处理后的记录写入XML 使用onSkipInProcess()、onSkipInRead()和onSkipInWrite

我定义了一个块,提交间隔为10,跳过限制为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;

}
}
公共类XReader实现ItemReader{
@自动连线
私有xdao;
private List lst=new ArrayList();
私有整数指数=0;
public Object read()引发异常、UnexpectedInputException、ParseException、NonTransientResourceException{
if(lst.isEmpty()){
lst=classDao.findAll();
} 
如果(索引
ItemProcessor类:

public class XProcessor<T> implements ItemProcessor<T, T> {
public Object process(Object item) throws Exception {
    // logic here
}
公共类XProcessor实现ItemProcessor{
公共对象进程(对象项)引发异常{
//这里的逻辑
}
ItemWriter类:

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

public void write(List您需要一个如下所示的侦听器实现。每当发生异常时,它会调用相应的方法,如果您愿意,您可以处理,否则只需将该方法保留为空。这样它就不会失败

它也不会调用处理器两次

xml配置:

<batch:listeners>
                    <batch:listener ref="recordSkipListener"/>
                  </batch:listeners>
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) {


    }
}

侦听器类:

<batch:listeners>
                    <batch:listener ref="recordSkipListener"/>
                  </batch:listeners>
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) {


    }
}
公共类RecordSkipListener实现SkipListener{
@凌驾
公共无效OnSkipRead(可丢弃的t){
}
@凌驾
公共无效onSkipInWrite(模型项,可丢弃的t){
}
@凌驾
公共无效OnSkipin流程(模型项,可丢弃的t){
}
}

在容错步骤中使用
ItemProcessor
s时,它们应该是幂等的,因为它们有被多次调用的风险(如示例所示)。您可以在此处的文档第6.3.3节中了解更多信息:

您是否有实现SkipListener的侦听器类?您的处理器是否
scope=step?
您是否尝试将
重试限制设置为0?scope=“step”和重试限制仅在我执行此操作时才给出相同的结果。但仍然存在相同的问题。