Grails事务中save(flush:true)的归属、回滚及独立事务实现问题
问题1:调用author.save(flush:true)的操作是否仍处于当前事务范围内?
- 是,该操作仍然完全处于当前事务的管控范围内。
flush:true的作用仅为将Hibernate会话中暂存的实体变更同步写入数据库的事务上下文,不会触发当前事务的提交操作,因此不会脱离现有事务边界。
问题2:若后续整个事务执行失败,已执行flush的author数据是否会被Grails回滚?
- 会被回滚。flush只是将数据写入了数据库的未提交事务缓存区,只要当前主事务未完成最终提交,触发回滚时数据库会撤销本次事务内所有未提交的变更,已经flush的author写入操作也会被同步撤销。
问题3:需编写什么代码才能让author.save(flush:true)成为独立的非事务操作,即使后续主事务失败,author数据仍可成功保留在数据库中?
你需要将author的保存逻辑抽为独立方法,并配置事务传播级别为 REQUIRES_NEW,该级别会在方法执行时挂起当前主事务,开启一个全新的独立事务,方法执行完成后会立刻提交这个独立事务,后续主事务的任何异常、回滚都不会影响它的执行结果。
示例实现如下:
- 新增独立保存author的方法,配置对应事务属性(建议写在独立Service类中,避免同Bean自调用导致事务切面失效):
import org.springframework.transaction.annotation.Propagation import grails.transaction.Transactional @Transactional(propagation = Propagation.REQUIRES_NEW) def saveIndependentAuthor() { def author = new Author() // 此处补充author的属性赋值逻辑 return author.save(flush: true) }
- 在原主事务方法中调用该独立方法:
@Transactional def saveMyBook() { // 调用独立事务方法,执行完成后author已被独立事务提交,不受后续逻辑影响 saveIndependentAuthor() def book = new Book() def pricing = new Pricing() book.save() pricing.save() }
提示:如果需要将
saveIndependentAuthor放在当前Service类中,不要直接调用本类的该方法,需通过Grails应用上下文获取当前类的代理对象后再调用,否则事务切面不会生效,无法正常开启独立事务。
内容的提问来源于stack exchange,提问作者tom6502
相关产品推荐
相关产品推荐

