我有一个 spring 批次使用编写器重试 . 作者看起来像这样:
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启动应用程序和spring jdbc .
2 回答
不要那样控制重试 . 使用Spring Batch的重试逻辑 . Spring Batch将回滚事务并以安全的方式重试 . 您重试的方式是,重试不与事务协调,因此您将获得重复记录(因为事务未回滚) .
使用spring jdbc,您将使用事务管理器 . 使用它来控制设置事务边界并在更新查询后提交它 .
另请参阅this示例,它介绍了如何使用事务管理器 .