一尘不染

在Grails服务中回滚事务

hibernate

当服务中抛出RuntimeException时,我使用Grail的回滚功能将所有服务更新为事务性。在大多数情况下,我都这样做:

def domain = new Domain(field: field)
if (!domain.save()) {
   throw new RuntimeException()
}

无论如何,我想验证这是否确实会回滚事务……这让我开始思考是否在这一点上已经提交了。此外,如果没有,设置flush:true会改变这一点吗?我对Spring
/ Hibernate如何完成所有这些工作不是很熟悉:)


阅读 327

收藏
2020-06-20

共1个答案

一尘不染

是的,那样做。

默认情况下,Grails中的事务是在Service方法级别处理的。如果该方法正常返回,则将提交事务,如果引发RuntimeException,则将回滚该事务。

请注意,这意味着即使在将对象保存在服务器方法中的同时使用flush:true,如果抛出RuntimeException,数据库更改仍将回滚。

例如:

class MyService {

 def fiddle(id,id2){
   def domain = Domain.findById(id)

   domain.stuff = "A change"
   domain.save( flush:true ) // will cause hibernate to perform the update statements

   def otherDomain = OtherDomain.findById(id2)

   otherDomain.name = "Fiddled"

   if( !otherDomain.save( flush:true )){ // will also write to the db
     // the transaction will be roled back 
     throw new RuntimeException("Panic what the hell happened")
   }                                                           
 }
}

我对Grails的理解不是100%清楚的是,如果在直接的java /
spring世界中抛出了检查异常,将会发生什么,默认行为是让事务接收器提交事务,因此可以在配置中覆盖它。

注意:有一个警告,那就是您的数据库必须支持您要更新的表上的事务。是的,这是MySQL的问题:)

这也适用于该Domain.withTransaction方法。

2020-06-20