【问题标题】:Spring Batch : Skip a record that cannot be written to the database and proceed with the next recordSpring Batch:跳过无法写入数据库的记录并继续下一条记录
【发布时间】:2019-11-08 05:28:16
【问题描述】:

给定一个 Spring Batch 作业,它使用面向块的处理从文件中读取数据,对数据执行一些处理并将转换后的记录写入数据库,有没有办法跳过记录如果写入数据库时​​出现异常并继续下一条记录? (某种拦截器?)

另外,据我了解,当无法写入给定块中的记录时(例如,值大于数据库列的长度),整个块将失败。我想要的是将此记录传递给某个拦截器,然后该拦截器可以尝试通过更正值或将错误记录写入某个日志文件来解决问题并继续下一条记录,而不是使批处理失败。我知道 Spring Batch 提供了一些在异常时触发的内置侦听器,但我无法弄清楚如何使用它们来做我想做的事情。

如何在 Spring Batch 中实现这一要求?

【问题讨论】:

标签: java spring exception spring-batch


【解决方案1】:

有没有办法跳过一条记录,以防在写入数据库时​​出现异常并继续下一条记录?

使用容错步骤,您可以配置SkipPolicy。这是一个例子:

@Bean
public Step step1() {
   return this.stepBuilderFactory.get("step1")
            .<String, String>chunk(10)
            .reader(flatFileItemReader())
            .writer(itemWriter())
            .faultTolerant()
            .skipLimit(10)
            .skip(FlatFileParseException.class)
            .build();
}

在这个例子中,每当FlatFileParseException 发生时,相应的项目就会被跳过。您可以在参考文档的Configuring Skip Logic 部分找到更多详细信息。

我想要的是将此记录传递给某个拦截器,然后该拦截器可以尝试通过更正值或将错误记录写入某个日志文件来解决问题

您可以通过注册SkipListener 获得有关跳过项目的通知。例如,这是将跳过的项目记录到文件的正确位置。

并继续下一条记录,而不是使批次失败

当在写操作过程中抛出可跳过的异常时,Spring Batch 会扫描块中的错误项(因为它无法知道是哪个项导致了错误)。从技术上讲,Spring Batch 会将块大小设置为 1,并且每个项目使用一个事务,因此只会回滚有问题的项目。这使您可以实现上述要求。您可以找到代码示例here

【讨论】:

  • 感谢您的快速回复;但是,我正在寻找的是一种通过修复错误将记录写入数据库的方法。例如,假设由于特定字段值大于数据库表中列的大小而无法写入记录。在这种情况下,如果列不是那么重要(我们知道重要的列的列表),我可以将值截断为数据库接受的大小并继续前进,而不是让我的整个批处理失败很重要。我找不到拦截步骤和处理错误记录的方法。
  • 在这种情况下,它不是跳过,而是重试:您正在重试写入项目(在重新处理它以截断它之后)。所以你需要配置一个RetryPolicy
  • 注明。重试策略是否需要 saveState=true?使用 using RetryPolicy 是否依赖于以某种方式编写作业?换句话说,使用 RetryPolicy 的前提是什么?我们正在使用 spring abtch 的功能,我们不能使用 saveState=true 等选项。
  • 在job的同一次运行中会应用重试策略,与job仓库中保存的状态无关
  • 我找不到很好的例子来做到这一点。如何使用重试策略更正我的项目的价值?据我了解,重试只会重新运行处理器和编写器?我如何知道哪个项目失败以及在哪里截断它的值。你能指出一个例子来证明这一点,因为这个特殊的用例很难找到..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 2018-11-20
相关资源
最近更新 更多