Grails在保存时回滚withTransaction

时间:2014-11-19 12:00:04

标签: grails

我正在测试withTransaction,但我遇到了一些问题。为什么我保存一个对象后,我无法回滚它?例如

Domain1 obj1 = new Domain(name: "obj1")
Domain1.withTransaction { status ->
    if(obj1.save(flush:true)){ //save the object, has no errors
        Domain2 obj2 = new Domain(name: asdasd) // making error happen
        if(!obj2.save(flush:true)){ // dont save, because its not string
            status.setRollbackOnly() // rollback the obj1
        }
    } else{
    throw new PersistenceException("error", obj1.errors)
    }
}

还有另一种回滚save()?

的方法

1 个答案:

答案 0 :(得分:1)

在使用事务时,必须考虑Hibernate如何处理基础持久性会话的重要注意事项。回滚事务时,GORM使用的Hibernate会话将被清除。这意味着会话中的任何对象都会分离,访问未初始化的延迟加载集合将导致LazyInitializationExceptions。

要理解为什么清除Hibernate会话很重要。请考虑以下示例:

class Author {
    String name
    Integer age

static hasMany = [books: Book] }

如果您要使用连续交易保存两位作者,如下所示:

Author.withTransaction { status ->
    new Author(name: "Stephen King", age: 40).save()
    status.setRollbackOnly()
}

Author.withTransaction { status -> new Author(name: "Stephen King", age: 40).save() }

由于第一个事务通过清除Hibernate会话回滚作者save(),因此只保存第二个作者。如果没有清除Hibernate会话,那么两个作者实例都会被持久存在,并且会导致非常意外的结果。

但由于会话被清除,因此获取LazyInitializationExceptions会令人沮丧。