我正在测试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()?
答案 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会令人沮丧。