Spring Data:重试时回滚事务

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Data:重试时回滚事务相关的知识,希望对你有一定的参考价值。

有一个实体:

@Entity
class A {
    ...
    @Version
    int version; 
}

以乐观的方式实施A实例更新:

@Transactional(rollbackFor = {StaleStateException.class})
@Retryable(value = {StaleStateException.class})
public void updateA() {
    A a = findA();
    B b = new B();
    // Update "a" somehow
    a.update();
    // "b" is saved on each retry!
    save(b);
}

如评论中所述,当qazxsw poi出现时,似乎事务不会回滚,因此qazxsw poi实例会在每次重试时保存。

是否可以在重试时回滚事务?

期望的行为是qazxsw poi仅在成功的qazxsw poi更新时提供。

答案

我认为它可能与StaleStateException配置有关。

正如文档所说,B无状态可重试只不过是一个循环,它一直调用相同的方法直到它成功。

问题是,每次失败时,第一个被调用的拦截器都是可重试的,不会重新抛出异常,所以它永远不会到达b

所以会发生的是,每次重试都将遵循默认的事务传播,这将在上下文中重用与a相同的已打开事务。

您可以通过调试检查我是否在正确的线索上:如果您输入第二次重试并发现@Retryable已在更新块之前更新,那么我应该是正确的。

您可以通过两种方式修复:

将两个块分开(首先使用嵌套事务重试)

https://docs.spring.io/spring-batch/trunk/reference/html/retry.html#statelessRetry

这样事务就会先回滚。

或者您可以关注文档并使用有状态重试@Transactional

以上是关于Spring Data:重试时回滚事务的主要内容,如果未能解决你的问题,请参考以下文章

Spring Kafka - 事务回滚后重试时,通过侦听器容器事务发布消息和提交记录偏移失败

使用JPA的Spring数据不会在出错时回滚事务

外部事务失败时回滚内部事务

SpringBoot实现单元测试时回滚事务

SpringBoot实现单元测试时回滚事务

带有涉及两个 DAO 的遗留代码的 Spring 事务