Spring批处理具有提供声明性跳过策略(即skippable-exception-classes)的功能,以声明需要在批处理中跳过特定记录。
对于ItemReader和ItemProcessor,这是非常直接的(因为它们按记录基础进行操作)。
但是在ItemWriter的情况下,当记录的写入失败时(由于DB Constraint违规),我想跳过该记录并让其他记录通过。
据我所研究,我可以通过两种方式实现这一点,
1)抛出可跳过的异常,Spring Batch将开始重试操作,每批一个项目,因此如果原始批量大小为1000,那么批处理将调用编写器(和处理器,如果它是事务性的) )1000次(每次记录一次)并记录skipCount,这个项目因跳过异常而失败(很可能是在正常操作中失败的同一项目)
2)ItemWriter捕获SQLException,并继续处理下一条记录,直到项目列表结束。
第二种方法存在丢失有关未经过多少记录的统计信息(即跳过的记录)的问题,批次将记录所有项目已成功写入,因此更新写入计数的值不正确。
第一种方法在我的用例中有点棘手,因为它涉及重新执行所有项目(在DB端我们有复杂的SP +触发器),因此不必要地花费更多时间。
我正在寻找一些合法的替代方法来重试只是在写作阶段记录跳过的记录数。
如果没有,我会选择第一个选项。
谢谢!
答案 0 :(得分:0)
这指定在提交事务的编写器执行次数之后。
<chunk ... commit-interval="10"/>
由于您希望跳过持久保存到DB时失败的所有项目,因此您需要将commit-interval设置为1才能实际保留好项目,而不是沿着坏项目回滚。
假设读者只向处理器发送一个项目(而不是1000个列表)读取器,处理器和编写器将按顺序执行每个项目。在这种情况下,选项2)没有用,因为编写器总是只收到一个项目。
您可以通过调用此类中的StepContribution.html#incrementWriteCount和其他增量* Count方法来控制跳过计数的增加方式。