【问题标题】:Hibernate does not rollback in case of a runtime exception thrown如果抛出运行时异常,Hibernate 不会回滚
【发布时间】:2018-11-26 04:00:46
【问题描述】:

我的项目中有以下代码。第 4 行抛出异常,但我的产品详细信息仍被保存。我很难理解为什么即使在抛出异常后它也会保存产品详细信息 我还想了解第 4 行抛出的异常是检查异常还是未检查异常?如果我抛出“抛出新异常(“详细信息不匹配”)”,这是我假设的运行时异常?

class Product{
    @Transactional
        addDetails(){
            try{
            }
            catch (Exception e) {
               throw new Exception("Details dont match") //Line 4
            }
           productDAO.save(productDetails) 
           addAdditionalDetails(productDetails)
        }
       }

class ProductDAO {
   @Transactional
   public void save(Product productDetails){
       entitiyManager.merge(productDetails)
   }
}

【问题讨论】:

标签: java hibernate spring-jdbc spring-orm


【解决方案1】:

我也想了解第 4 行抛出的异常是否是 已检查或未检查的异常?

答案:java.lang.Exception 是一个检查异常。

如果我抛出 "throw new Exception("Details don't match")" 这是一个 我假设的运行时异常?

回答:不,它不是RuntimeException。 RuntimeException 是扩展 java.lang.RuntimeException 或其 subclass 的那些。

在春季发生Runtime 异常时,事务是回滚。这意味着在extends RuntimeException 或其子类的事务中抛出的任何异常都会回滚它。但是在您的情况下,您正在抛出Exception,这不是RuntimeException 的类型。

解决方案:

我会建议创建一个扩展 RuntimeExction 的自定义异常并抛出它。

class UnmatchedDetailException extends RuntimeException{
    UnmatchedDetailException(String msg){
        super(msg);
    }
}

然后抛出UnmatchedDetailException

throw new UnmatchedDetailException("Deatils not matched");

【讨论】:

    【解决方案2】:

    使用默认的 spring 配置,只有未检查的运行时异常会被回滚。为了自定义此配置,rollbackFor 用作 @Transactional 注释中的属性。

    例如,

    @Transactional(rollbackFor = { MyInvalidUserException.class, MyApplicationException.class }) public void method() throws 我的无效用户异常,我的应用程序异常 { ... ... }

    【讨论】:

      猜你喜欢
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 2020-09-24
      • 1970-01-01
      • 2013-05-01
      • 2012-08-21
      • 1970-01-01
      相关资源
      最近更新 更多