在 Grails 下如何防止异常导致事务回滚?

2024-05-07

我的 Grails 服务遇到一个问题,即与事务无关的吞没异常会导致事务回滚,即使它与域对象的持久性无关。

在我的服务中,我有一些类似的东西

updateSomething(domainObj) {
    def oldFilename = domainObj.filename
    def newFilename = getNewFilename()

    domainObj.filename = newFilename
    domainObj.save(flush: true)

    try {
        cleanUpOldFile(oldFilename)
    } catch (cleanupException) {
        // oh well, log and swallow
    }
}

我看到的是,当我清理旧文件时出现异常时,我会记录它并吞下它,但它仍然会导致事务回滚,即使我已经完成了域对象的更新。

如何限制范围事务在清理之前完成,或者是否有其他方法可以使清理异常不会导致回滚?

仅供记录,我使用的是 Grails 2.1.1


您可以使用注释来进行更细粒度的事务划分。默认情况下,服务是事务性的,并且所有公共方法都是事务性的。但如果你使用任何@Transactional注释,Grails 并不使所有事情都成为事务性的——您拥有完全的控制权。

运行时异常会自动触发回滚,但检查异常则不会。尽管 Groovy 不要求您捕获已检查的异常,但该功能是 Spring 的功能,它不了解 Groovy 异常处理。

事务是通过将服务类实例包装在代理中来实现的。如果异常“逃逸”了代理,无论它是否被捕获,回滚都已经发生。

所以你有几个选择。注释updateSomething as @Transactional但不要注释cleanUpOldFile:

import org.springframework.transaction.annotation.Transactional

@Transactional
def updateSomething(domainObj) {
...
}

def cleanUpOldFile(...) {
   ...
}

您还可以使用一个或多个不应回滚事务的未经检查的异常(或在其他用例中应回滚的检查异常)来注释 cleanUpOldFile,例如

@Transactional(noRollbackFor=[FooException, BarException])
def cleanUpOldFile(...) {
   ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Grails 下如何防止异常导致事务回滚? 的相关文章

  • withTransaction 和 withNewTransaction 有什么区别?

    以下动作有什么区别 def someAction User withTransaction and def someAction User withNewTransaction 我什么时候用什么 当 grails 操作仅包含 Transac
  • 带回调或异步/等待的节点 postgres 事务?

    我正在运行 Node 7 6 0 它支持 async await node postgres 客户端池支持 async await 并且有一个很好的示例here https github com brianc node pg pool pl
  • Grails 默认包名称

    我是 Grails 的新手 而且非常喜欢它 我想将我的课程放在像这样的包中org company project module model 重复对我来说很痛苦create domain class
  • Grails Asset-pipeline 不加载角度部分模板

    我将 angular ui bootstrap 与 Grails 2 3 x asset pipeline 1 6 1 插件一起使用 其中一个组件 alert js 正在尝试加载 template alert alert html 但这会解
  • 使用 Hibernate 和 MySQL、全局和本地进行 Spring 事务管理

    我正在使用 MySQL Server 5 1 Spring 3 0 5 和 Hibernate 3 6 开发 Web 应用程序 我使用 Springs 事务管理 我是新手 所以如果我问一个容易回答的问题 请耐心等待 1 我读到了有关全局 x
  • grails/mysql 时区更改

    完成更改应用程序时区的最佳方法是什么 在我看来 必须发生以下情况 服务器 TZ 已被系统管理员更改 mysql必须重新启动 数据库中每个基于时间的列都必须使用convert tz 或等效方法更新所有值 因此 要么必须编写一个 mysql 脚
  • Grails transactionManager 运行时出现异常

    当编译一个grails v2 3 3项目运行项目时出现以下错误Netbeans 7 4 Loading Grails 2 3 3 Configuring classpath Configuring classpath Environment
  • 无法在 Zend Framework 中回滚事务

    我在 Zend Framework 中使用以下代码进行事务 但回滚功能不起作用 数据通过 insertSome data 插入数据库 怎么了 db gt beginTransaction try model gt insertSome da
  • 打开新EntityManager后线程锁

    我在使用 Spring JPA 事务时遇到一个非常奇怪的错误 该线程被锁定大约 16 分钟 然后继续 没有任何问题 情况如下 Transactional propagation Propagation REQUIRES NEW public
  • 类权限不是域类或 GORM 尚未正确初始化或已关闭

    我正在开发一个 Grails 休息应用程序 我使用的grails版本是3 3 1 我正在使用 spring security rest 进行授权 我使用 s2 quickstart 命令创建了以下类 User 权威 用户权限 该应用程序运行
  • Java:多线程内的 XA 事务传播

    我如何使用事务管理器 例如Bitronix http docs codehaus org display BTM Home JBoss TS http www jboss org jbosstm or Atomikos http www a
  • UrlMapping 和文件扩展名

    我有以下 url 映射 name a a file controller attachment action get 我想像这样使用它
  • 如何在GEB中选择内部元素的文本?

    我有以下场景 div ul class select2 results style width 400px li class select2 results dept 0 select2 result select2 result sele
  • 在 Spring 中使用事务时创建提交后

    由于某些原因 我使用 Spring PlatformTransactionManager 手动执行事务提交和回滚 我需要做的是设置一个钩子 以便在提交事务后发生提交后操作 通过查看 void commit TransactionStatus
  • 为什么 GORM 不保存我的对象?

    如果我在 Grails 控制台中执行此代码 def p new Post title T p save flush true or p save Post count GORM 没有抛出任何异常 但数据没有保存在我的数据库中 我究竟做错了什
  • 在 Grails 中使用 Spring-Security 前/后注释

    我正在使用 Grails Spring Security 插件 Spring Security Core 1 0 1 它又使用 spring security 3 0 2 RELEASE 开发 Grails 版本 1 3 3 Web 应用程
  • 使用临时表替换 WHERE IN 子句

    我让用户输入我需要在表中查询的值列表 该列表可能非常大 并且长度在编译时未知 而不是使用WHERE IN 我认为使用临时表并对其执行联接会更有效 我在另一个SO问题中读到了这个建议 目前找不到它 但会在找到时进行编辑 要点是这样的 CREA
  • JPA 乐观锁与同步 Java 方法

    使用 JPA 乐观锁定 我们可以通过 Version 字段控制数据库表是否已被另一个事务同时更新 从而允许在数据库中存储可靠的数据 如果一个Java应用程序只有一个CRUD服务负责数据库中的特定实体 我们也可以同步其方法并管理信息在数据库中
  • 重复键错误不会取消/回滚mysql事务

    当在 mysql innodb 事务中时 我希望重复的键错误会导致回滚 它没有 相反 它只是抛出一个错误并继续执行下一个命令 一旦到达 COMMIT 命令 事务将被提交 没有重复键导致命令 这是预期的行为吗 如果是这样 如何设置它以便在发生
  • 使用 Grails GORM 从旧数据库中的 char 字段中去除尾随空格

    映射时去除尾随空格的可能解决方案有哪些char遗留数据库中的字段 我看到以下选项 Calling trim 在使用时 控制器 视图等 重写属性访问器以返回 trim 使用 Hibernate UserType 修剪空格 我倾向于重写属性访问

随机推荐