hibernate - 以编程方式处理 Grails 事务

标签 hibernate grails transactions grails-orm

当我需要保存一个对象列表,并且每个对象都应该保存在它自己的事务中时(这样如果一个失败,它们不会全部失败),我这样做:

List<Book> books = createSomeBooks()
books.each { book ->
  Book.withNewSession {
    Book.withTransaction {TransactionStatus status ->
      try {
        book.save(failOnError: true)
      } catch (ex) {
        status.setRollbackOnly()
      }
    }
  }
} 

我用 Book.withNewSession因为如果一本书保存失败并且事务回滚, session 将无效,这将阻止后续书籍保存。但是,这种方法存在几个问题:
  • 有点啰嗦
  • 将始终为每本书创建一个新 session ,即使前一本书成功

  • 有没有更好的办法?我想到的一种可能性是依赖注入(inject) Hibernate SessionFactory而是这样做
    List<Book> books = createSomeBooks()
    books.each { book ->
      try {
        Book.withTransaction {
          book.save(failOnError: true)
        }
      } catch (ex) {
        // use the sessionFactory to create a new session, but how....?
      }
    }
    

    最佳答案

    这应该这样做:

    List<Book> books = createSomeBooks()
    books.each { book ->
      Book.withNewTransaction {TransactionStatus status ->
        try {
          book.save(failOnError: true)
        } catch (ex) {
          status.setRollbackOnly()
        }
      }
    } 
    

    如果您回滚, session 不是无效的,它只是被清除。因此,任何访问从数据库读取的实体的尝试都会失败,但写入尚未持久化的实体会很好。但是,您确实需要使用单独的事务来防止一次失败回滚所有内容,因此需要使用 withNewTransaction。

    关于hibernate - 以编程方式处理 Grails 事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21805893/

    相关文章:

    hibernate - JPA 2.0 标准和谓词分组

    java - 使用 hibernate 的 JPA 2 标准查询无法左连接

    java - 如何在 Netbeans 中使用 sqlserver 和 jtds 驱动程序设置 Hibernate

    java - 邮件中HTML数据内容不正确

    spring - 使用@Transactional(readOnly = true) 有什么好处?

    java - Spring事务注解回滚测试好像不太顺利

    java - Hibernate集成测试-Jasypt加密跳过参数

    git - 在 Jenkins 上进行 git 时检查特定文件夹

    grails - 从 Groovy 类调用 grails 插件闭包

    java - 围绕 finder 方法的事务