当读取器发生异常时,不会调用Spring Batch SkipListener

时间:2011-10-03 18:11:55

标签: spring spring-batch

这是我的步骤配置。我的跳过侦听器onSkipInWrite()方法被正确调用。但onSkipInRead()没有被调用。我故意从读者那里抛出一个空指针异常,从而发现了这一点。

<step id="callService" next="writeUsersAndResources">
        <tasklet allow-start-if-complete="true">
            <chunk reader="Reader" writer="Writer"
                commit-interval="10" skip-limit="10">
                <skippable-exception-classes>
                    <include class="java.lang.Exception" />
                </skippable-exception-classes>
            </chunk>
            <listeners>
                <listener ref="skipListener" />
            </listeners>
        </tasklet>
    </step>

我阅读了一些论坛,并在两个级别上交换了listeners-tag:在chunk内部,以及在tasklet之外。没有什么工作......

在此处添加我的跳过侦听器

package com.legal.batch.core;

import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.batch.core.SkipListener;
import org.springframework.jdbc.core.JdbcTemplate;


public class SkipListener implements SkipListener<Object, Object> {


    @Override
    public void onSkipInProcess(Object arg0, Throwable arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSkipInRead(Throwable arg0) {
    }

    @Override
    public void onSkipInWrite(Object arg0, Throwable arg1) {
}

}

专家请建议

1 个答案:

答案 0 :(得分:12)

跳过侦听器尊重事务边界,这意味着它们总是在事务提交之前被调用。

由于示例中的提交间隔设置为“10”,因此在提交这10个项目时(立即)将调用onSkipInRead

因此,如果您尝试逐步调试,则在ItemReader抛出异常后,您不会立即看到onSkipInRead被调用。

示例中的SkipListener有一个空的onSkipInRead方法。尝试在onSkipInRead内添加一些日志记录,移动并重新运行作业以查看这些消息。

修改

这是一个工作示例[名称更改为'abc']:

<step id="abcStep" xmlns="http://www.springframework.org/schema/batch">
    <tasklet>
        <chunk writer="abcWriter"
               reader="abcReader"
               commit-interval="${abc.commit.interval}"
               skip-limit="1000" >

            <skippable-exception-classes>
                <include class="com.abc....persistence.mapping.exception.AbcMappingException"/>
                <include class="org.springframework.batch.item.validator.ValidationException"/>
                ...
                <include class="...Exception"/>
            </skippable-exception-classes>

            <listeners>
                <listener ref="abcSkipListener"/>
            </listeners>

        </chunk>

        <listeners>
            <listener ref="abcStepListener"/>
            <listener ref="afterStepStatsListener"/>
        </listeners>

        <no-rollback-exception-classes>
            <include class="com.abc....persistence.mapping.exception.AbcMappingException"/>
            <include class="org.springframework.batch.item.validator.ValidationException"/>
            ...
            <include class="...Exception"/> 
        </no-rollback-exception-classes>

        <transaction-attributes isolation="READ_COMMITTED"
                                propagation="REQUIRED"/>
    </tasklet>
</step>

abcSkipListener bean是:

public class AbcSkipListener {

    private static final Logger logger = LoggerFactory.getLogger( "abc-skip-listener" );

    @OnReadError
    public void houstonWeHaveAProblemOnRead( Exception problem ) {
        // ...
    }


    @OnSkipInWrite
    public void houstonWeHaveAProblemOnWrite( AbcHolder abcHolder, Throwable problem ) {
        // ...
    }

    ....
}