【问题标题】:Retry on spring batch writer重试春季批处理编写器
【发布时间】:2018-02-08 16:54:54
【问题描述】:

我有一个在编写器上使用重试的春季批次。作者长这样:

public class MyWriter implements ItemWriter<MyClass> {

  @Retryable(maxAttempts=3, backoff=@Backoff(delay=2000))
  public void write(List<? extends MyClass> list) throws Exception {
    // db operation 1 -- insert query
    // some business logic 
    // db operation 2 -- update query
  }
} 

如果“db operation 2”出现异常,则调用重试并按预期再次从“db operation 1”开始执行。但是“db operation 1”是一个插入查询,这次会抛出异常,因为它试图再次插入相同的记录(并且对 DB 的唯一约束失败)。最终,批处理在 3 次尝试后失败,并且此步骤中的任何内容都不会提交到数据库。

在重试之前不应该回滚/刷新“db operation 1”吗?这是预期的行为还是实施有问题?

我正在使用 Spring Boot 应用程序和 Spring jdbc。

【问题讨论】:

    标签: spring spring-batch


    【解决方案1】:

    使用您的 spring jdbc,您将使用事务管理器。使用它来控制设置事务边界并在更新查询后提交。

    另请参阅this 示例,它描述了如何使用事务管理器。

    【讨论】:

    • 我没有配置事务管理器,因为 Spring Batch 自己管理事务。它的事务按预期工作,并且仅在更新查询之后才发生提交。问题是它认为插入已经发生在重试时,即使它尚未提交。
    【解决方案2】:

    不要以这种方式控制重试。使用 Spring Batch 的重试逻辑。 Spring Batch 将回滚事务并以安全的方式重试。您重试的方式,重试不与事务协调,因此您得到重复的记录(因为事务没有回滚)。

    【讨论】:

    • 是否可以更精确地使用 Spring Batch 的重试逻辑?是通过添加可跳过的异常、可重试的异常,还是在编写器类中使用 retryTemplate?你到底是怎么推荐的?
    猜你喜欢
    • 1970-01-01
    • 2019-03-26
    • 2020-08-10
    • 2019-03-24
    • 1970-01-01
    • 2018-04-03
    • 2014-12-15
    • 2018-05-27
    • 2015-05-13
    相关资源
    最近更新 更多