Spring Batch Rollback项目

我正在使用Spring Batch从XML到数据库导入项目 . 导入后,我创建了包含无效记录的日志 . 我通过配置可跳过的异常来获取这些项目:

<batch:chunk reader="reader" processor="processor" writer="writer" commit-interval="10" skip-limit="99999999">
    <batch:skippable-exception-classes>
        <batch:include class="java.lang.Exception"/>
    </batch:skippable-exception-classes>
    <batch:listeners>
        <batch:listener ref="recordSkipListener"/>
        <batch:listener ref="itemReadListener"/>
    </batch:listeners>
</batch:chunk>

我执行后的日志:

Start time: 30.12.2015 01:05:38
End time: 30.12.2015 01:20:59
Read count: 3842
Skip count: 0
Write count: 3522

通过此表达式计算的跳过计数:

int skipCount = stepExecution.getReadSkipCount() + stepExecution.getProcessSkipCount() + stepExecution.getWriteSkipCount();

“RecordSkipListener”处理处理器和编写器中抛出的所有异常,但它在步骤执行期间从不调用读取,处理和写入方法 . 仅调用ChunkListener.afterChunkError方法,但其参数不包含有关失败记录的信息 . 因此我有两个问题:

  • 如何记录失败的项目?

  • 为什么Spring Batch没有实现与ItemWriter.write上的行为相同的行为:失败的块被分成大小= 1的块然后在专用事务上处理?

//更新

即使我将块大小减少到1,也不会写入大约50条记录 . 我无法记录他们的 .

回答(2)

2 years ago

我会以相反的顺序回答你的问题:

Why Spring Batch doesn't implement behavior same as behavior on ItemWriter.write: failed chunk are divided onto chunks with size=1 and then processed on dedicated transaction?

在步骤的处理或写入阶段抛出异常时,我们可以提供导致错误的项目,因为我们有一个有效的项目 . 在读取阶段发生异常的问题是,由于抛出了异常,我们没有任何项目可以提供给任何人 . 读者必须传达导致异常的输入的唯一方法是将有关该输入的信息嵌入到抛出的异常中 . 一个例子是在解析 FlatFileItemReader 中的一行期间抛出异常时,我们抛出一个 FlatFileParseException . 该异常包含行号和导致异常的行的内容 . 您可以使用 ItemReadListener#onReadError 方法捕获异常并获取异常中提供的信息 .

How I can log failed items?

使用XML,能够提供对错误的洞察力是很困难的,因为它控制(它实际上是unmarshaller的功能以及那里出了什么问题) . 您可以做的最好的事情是从记录计数中归咎坏记录(通过 ExecutionContext ) . 这将告诉您在XML文件中导致错误的数字记录 .

2 years ago

这个问题的问题在于,chunk commiting是例外:实体字段之一的长度超出了允许的大小 . 在这种情况下,处理和写入不会重试