【问题标题】:Transactional Method not rolling back for unchecked Exception事务方法不回滚未经检查的异常
【发布时间】:2021-02-22 04:53:10
【问题描述】:
@Service
public class TransactionClass{

    @AutoWire
    TransactionClass tranClass;

    @Autowire
    TransactionRepository transRepo;

    public void methodA(Data data){
        try{
             methodB(data)
        }catch(Exception e){
            //some logic
        }
   }

   public void methodB(Data data){
       //some logic
       tranClass.methodC(data)
   }

  @Transactional
  public void methodC(Data data){
      //some logic
      transRepo.save(data);
      throw new RuntimeException();
  }
}

问题是即使抛出未经检查的异常,methodC() 也没有回滚。

【问题讨论】:

  • 因为 methodC() 没有进行中的事务,如欺骗中所述。唯一的交易将发生在transRepo.save(data);
  • 但我只想在methodC中发生回滚。但即使在 transRepo.save(data); 之后抛出运行时异常;仍然数据保存在数据库中。
  • 哦,我没有注意到您正在为TransactionClass 进行自我注入。这就是它通常应该如何工作,所以错误可能在你的实际代码中的某个地方。
  • 怎么调用methodC?
  • @Mick methodC() 使用 TransactionClass 的引用来调用。

标签: java spring jpa exception transactions


【解决方案1】:

要使用日志检查事务如何工作,只需将其添加到 application.yaml

logging.level.org.springframework.transaction.interceptor: TRACE
logging.level.org.springframework.orm.jpa.JpaTransactionManager: DEBUG

logging.level.org.hibernate.SQL: DEBUG
spring.jpa.properties.hibernate.use_sql_comments: true

【讨论】:

    【解决方案2】:

    @v.ladynev 在日志中确实显示回滚已启动,但每次都将数据保存在数据库中。

    10-11-2020 16:54:50.221 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] 调试 org.springframework.orm.jpa.JpaTransactionManager.doBegin - 将 JPA 事务公开为 JDBC [org. springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@527770c1] 2020 年 10 月 11 日 16:54:50.222 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] TRACE org.springframework.transaction.interceptor.TransactionInterceptor.prepareTransactionInfo - 获取交易 [com.sample.TransactionClass.methodC ] 10-11-2020 16:54:50.224 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] TRACE org.springframework.transaction.interceptor.TransactionInterceptor.completeTransactionAfterThrowing - 为 [com.sample.TransactionClass.methodC 完成交易] 异常后:java.lang.RuntimeException 10-11-2020 16:54:50.225 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute.rollbackOn - 应用规则来确定事务是否应在 java 上回滚。 lang.RuntimeException 10-11-2020 16:54:50.226 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute.rollbackOn - 获胜回滚规则为:null 10-11-2020 16:54:50.227 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute.rollbackOn - 未找到相关回滚规则:应用默认规则 10-11-2020 16:54:50.228 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] 调试 org.springframework.orm.jpa.JpaTransactionManager.processRollback - 启动事务回滚 10-11-2020 16:54:50.229 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] 调试 org.springframework.orm.jpa.JpaTransactionManager.doRollback - 在 EntityManager [SessionImpl(281191562) 上回滚 JPA 事务] 10-11-2020 16:54:50.405 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] 调试 org.springframework.orm.jpa.JpaTransactionManager.doCleanupAfterCompletion - 事务后不关闭预绑定 JPA EntityManager 2020 年 10 月 11 日 16:54:50.405 [fcef5a02c2fb4941/28df25ce03f36cfe] [http-nio-8082-exec-8] 错误 com.sample.TransactionClass.methodC - 异常: java.lang.RuntimeException:空 在 com.sample.TransactionClass.methodC(TransactionClass.java:110) 在 com.sample.TransactionClass$$FastClassBySpringCGLIB$$a876827.invoke() 在 org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) 在 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) 在 org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

    【讨论】:

      【解决方案3】:

      事务方法没有回滚,因为它有多个数据库连接。所以@Transactional 将回滚唯一的主要配置,我们也可以在应用程序中只有一个主要配置。解决方案是使用链式事务。

      有关链式交易的更多信息,请参阅此链接: https://blog.usejournal.com/springboot-jpa-rollback-transaction-with-multi-databases-53e6f2f143d6

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-20
        • 2013-05-17
        • 1970-01-01
        • 2013-10-16
        • 2021-03-23
        • 2018-12-24
        • 2015-03-21
        相关资源
        最近更新 更多