【问题标题】:How does spring transactions at various levels work?各个级别的 Spring 事务是如何工作的?
【发布时间】:2019-08-01 14:01:01
【问题描述】:

如代码所示,我有 A 类和 B 类。 在提到的代码中,交易将如何表现? B类内部,commit之后会因为isolation_level而关闭事务吗?

Class A{
 @Transactional(propagation = Propagation.REQUIRED)
    method classAMethod(){
       B b = new B();
       b.classBMethod
    }
}

Class B{
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)

  method classAMethod(){
     B b = new B();
     b.classBMethod
  }

}

我正在运行一个批处理作业,一段时间后遇到“执行失败无法回滚 JPA 事务;嵌套异常是 javax.persistence.PersistenceException:回滚时出现意外错误” 异常,我怀疑上面提到的代码是导致问题的原因。

【问题讨论】:

    标签: spring jpa spring-transactions


    【解决方案1】:

    好吧,@Transactional.isolation 的 Javadoc 声明:

    专为与 Propagation.REQUIRED 或 Propagation.REQUIRES_NEW 一起使用而设计,因为它仅适用于新启动的事务。 如果您希望在参与具有不同隔离级别的现有事务时拒绝隔离级别声明,请考虑将事务管理器上的“validateExistingTransactions”标志切换为“true”。

    AbstractPlatformTransactionManager.validateExistingTransactions 的 Javadoc 说:

    当参与现有事务时(例如,使用 PROPAGATION_REQUIRED 或 PROPAGATION_SUPPORTS 遇到现有事务),此外部事务的特征甚至适用于内部事务范围。验证将检测内部事务定义上不兼容的隔离级别和只读设置,并通过抛出相应的异常拒绝参与。

    默认为“false”,忽略内部事务设置,简单地用外部事务的特征覆盖它们。将此标志切换为“true”以强制执行严格验证。

    从上面你可以得出结论,如果没有将validateExistingTransactions 设置为true,即使隔离级别与请求的隔离级别不同,事务也会继续进行。 “外部”事务特征优先。

    【讨论】:

    • 非常感谢您的回复。但是我仍然有点困惑,因为在我的应用程序中我尝试了同样的事情,似乎应用程序的行为已经改变。早些时候,在只有我的 A 类具有事务注释的多线程的情况下,我遇到了死锁问题。但后来我在 B 类中引入了一个具有隔离级别的事务级别(@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)),它似乎解决了我的问题。
    • TBH 我现在才注意到您正在方法中创建B 的新实例。在这种情况下,您如何注释 B 并不重要,因为您调用的实例不是 bean。 @Transactional 仅适用于 bean
    猜你喜欢
    • 1970-01-01
    • 2015-05-31
    • 2013-10-31
    • 2015-07-21
    • 2020-06-07
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多