当我需要保存一个对象列表,并且每个对象都应该保存在它自己的事务中时(这样如果一个失败,它们不会全部失败),我这样做:
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 将无效,这将阻止后续书籍保存。但是,这种方法存在几个问题:有没有更好的办法?我想到的一种可能性是依赖注入(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/