读写操作中的奇怪跳过侦听器行为

时间:2012-02-26 21:48:20

标签: spring spring-batch

我的工作是读取11条记录的平面文件。我在阅读器中跳过1个项目,在写入者中跳过4个我有一个Skiplistener SkipInRead()SkipInWrite()方法,它可以简单地在DB中记录跳过消息。为什么我的onSkipInRead被多次调用,即在这种情况下被调用3次,结果在DB中记录3次相同的消息。 OnSkipinWrite工作正常

<job id="ex_Job">
    <step id="load">
        <tasklet>
            <chunk reader="reader" writer="writer" commit-interval="3" skip-limit="10">
                <skippable-exception-classes>
                    <include class="org.springframework.batch.item.file.FlatFileParseException" />
                    <include class="org.springframework.batch.item.file.transform.IncorrectLineLengthException" />
                    <include class="org.springframework.dao.DataIntegrityViolationException"/>
                </skippable-exception-classes>
            </chunk>
            <listeners>
                <listener ref="genericSkipListener" />
            </listeners>
        </tasklet>
    </step>
</job>

public class GenericSkipListener extends AbstractBaseSkipListener implements
    SkipListener<FieldSet, FieldSet> {

private static final Log LOGGER = LogFactory.getLog(GenericSkipListener.class);

@Autowired
private SkipedItemsDao skipedItemsDao;


@Override
public void onSkipInRead(final Throwable t) {
    LOGGER.warn("[" + getJobName() + "] onSkipInRead:" + t);
    skipedItemsDao.saveReadSkippedItem(createReadSkipedItem("READ", "", t));
}

@Override
public void onSkipInWrite(final FieldSet item, final Throwable t) {
    LOGGER.warn("[" + getJobName() + "] onSkipWrite:" + t);
    skipedItemsDao.save(createSkipedItem("WRITE", item.toString(), t));
}

@Override
public void onSkipInProcess(final FieldSet item, final Throwable t) {
    LOGGER.warn("[" + getJobName() + "] onSkipInProcess:" + t);
    skipedItemsDao.save(createSkipedItem("PROCESS", item.toString(), t));
}
}

我的onSkipInRead()方法正在为同一项目多次调用。伙计们好吗?

1 个答案:

答案 0 :(得分:0)

  • 我在阅读器中跳过1项

做什么?

  • 同一项目的多次

只有当你自己重读同一个项目,或者确实在你的文件中重复了一次不良项目3次时,这才有可能。

    在这种情况下,
  • 3次
在读取提交间隔(它遵循事务边界)后调用

onSkipInRead,因此您可能有一个“跳过”提交间隔的项目。如果它是例如每第3项:

11 % 3 = 3 bad items skipped

在问题澄清之后编辑(在评论中)

要跳过文件中的前X行,请在linesToSkip上设置FlatFileItemReader

/** 
 *  Public setter for the number of lines to skip at the start of a file. 
 *  Can be used if the file contains a header without useful (column name) information, 
 *  and without a comment delimiter at the beginning of the lines.
 *
 *  linesToSkip - the number of lines to skip
 **/
public void setLinesToSkip( int linesToSkip ) { // ... }

或者/并且,如果对第一个跳过的行有任何特殊需要:

/**
 * skippedLinesCallback - will be called for each one of the initial skipped lines 
 * before any items are read. 
 **/
public void setSkippedLinesCallback( LineCallbackHandler skippedLinesCallback ) { // ... }