【问题标题】:Transaction rolled back because it has been marked as rollback-only - UnexpectedRollbackException事务回滚,因为它已被标记为仅回滚 - UnexpectedRollbackException
【发布时间】:2022-01-12 21:15:19
【问题描述】:

我有这样的代码:

@Service
public class AService {


      public void methodA() {
           try {
               methodB();
            } catch (Exception e) {
               methodC(e);
            }
       }

 }

methodB 正在从 DB 中读取。 如果发生在数据库中,methodC 正在写入异常。 出于某种原因,当方法 B 抛出错误时,方法 C 中的写入不起作用,我得到 - UnexpectedRollbackException: Transaction roll back because it has been marked as rollback-only.

不胜感激,谢谢!

【问题讨论】:

  • 请添加methodB()methodC()的代码。此外,请包括所有与交易相关的注释。谢谢!
  • 试试这个answer的解决方案

标签: java spring hibernate


【解决方案1】:

如果在 DB 访问期间发生异常,Hibernate 将 generally 将完整事务标记为 rollbackOnly,即使有人会通过 @Transactional(noRollbackFor=Exception.class) 注释属性显式尝试避免这种行为。

因此,在这些情况下,需要有不同的解决方案,例如为两个方法调用设置单独的事务。

(类似问题:handle sql exception for large data insert

【讨论】:

    【解决方案2】:

    我假设您在 methodB 的某个地方有一个由 Spring (@Transactional) 管理的事务。在 Spring 中,当在该事务中抛出 RuntimeException 时,该事务被标记为回滚。

    来自 Spring 文档:

    在其默认配置中,Spring Framework 的事务基础结构代码仅在运行时、未经检查的异常情况下将事务标记为回滚;也就是说,当抛出的异常是 RuntimeException 的实例或子类时。

    见:https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html#transaction-declarative-rolling-back

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      相关资源
      最近更新 更多