这是我的步骤配置。我的跳过侦听器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) {
}
}
专家请建议
答案 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 ) {
// ...
}
....
}