【问题标题】:Grails, save domain class after exception has been thrownGrails,抛出异常后保存域类
【发布时间】:2018-09-18 23:49:31
【问题描述】:

使用 grails 3.3.8

如果在发出保存的服务方法中抛出了捕获的异常,则不会保存任何 domainclass.save(flush:true,failOnError:true)。即

try {
    //some code that throws exception
} catch (Exception exception) {
    print 'some message'
}

domainclass.save(flush:true,failOnError:true)

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    我找到了解决上述问题的方法。如果您提取您的 try catch 块并将其放在不同的方法中,则域类保存会得到持久化。

    callMethodThatContainsTryCatch()
    domainClass.save()
    

    而不是

    try {
    } catch (Exception exception) {
        println "some exception"
    }
    
    domainClass.save()
    

    您的方法中的任何异常都会回滚该方法中的所有 gorm 事务。

    【讨论】:

      【解决方案2】:

      好吧,在 Grails 3.1 之前,服务默认是事务性的,从 Grails 3.1 开始,它们只有在应用 @Transactional 注释时才是事务性的。

      如果您在触发异常时使用事务服务,则事务将被标记为回滚。同时,当事务回滚时,GORM 使用的 Hibernate 会话被清除。

      我假设您的服务被标记为@Transactional。这就是您的域没有被保存的原因。要解决上述行为,您可以将您的服务标记为@NotTransactional。这将为您提供对服务方法的更多控制,只是要知道它不再是事务性的。并且抛出异常后不会清除 GORM 会话。

      编辑: 因为您正在调用.save(),所以强烈建议在事务中执行此操作。然后您可以使用withTransaction(Closure) 方法。

      【讨论】:

      • "要避免上述行为,您可以将您的服务标记为@NotTransactional。这将为您提供对服务方法的更多控制,请注意它不再是事务性的。" - 提倡在事务之外保存实例是个坏主意。
      • 这正是我为什么要意识到它不再是交易而发表评论的原因。我就这方面的帖子做了一个版本。谢谢@JeffScottBrown
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 2014-12-15
      • 2016-04-07
      • 2018-06-28
      相关资源
      最近更新 更多