在Grails服务中回滚事务 [英] Rolling back a transaction in a Grails Service

查看:172
本文介绍了在Grails服务中回滚事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直使用Grail在服务中抛出RuntimeException时回滚的能力来更新我的所有服务,使其成为事务性的。我在大多数情况下是这样做的:

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

无论如何,我想验证这确实会回滚事务......它让我想到在这一点上它是否已经被提交。另外,如果没有,会设置flush:真正的改变呢?我不是很熟悉Spring / Hibernate是如何完成这些的:)

解决方案

p>

默认情况下,Grails中的事务是在Service方法级别处理的。如果方法正常返回,则事务将被提交,如果抛出RuntimeException,事务将被回滚。注意这意味着即使在服务器方法中保存对象时使用flush:true on,如果抛出RuntimeException,数据库更改仍将回滚。

p>

例如:

  class MyService {

$ {
def domain = Domain.findById(id)

domain.stuff =变更
domain.save(flush:true) //会导致hibernate执行更新语句

def otherDomain = OtherDomain.findById(id2)

otherDomain.name =提琴

如果(!otherDomain.save(flush:true)){//也将写入db
//事务将被回溯
抛出新的RuntimeException(恐慌到底发生了什么)
}
}
}

我不是100%如果在直接的java / spring中引发一个检查过的异常,那么Grails就会发生什么世界默认的行为是交易inceptor提交交易,通过这可以在配置中重写。



注意:有一个警告,那就是你的db必须支持正在更新的表上的事务。是的,这是对MySQL的抨击:)

这也适用于 Domain.withTransaction 方法。

>

I have been updating all my services to be transactional by using Grail's ability to rollback when a RuntimeException is thrown in the service. I have, in most cases, doing this:

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

Anyways, I wanted to verify that this indeed will rollback the transaction... it got me thinking as to whether at this point it's already been committed.. Also, if not, would setting flush:true change that? I am not very familiar with how Spring/Hibernate does all of this :)

解决方案

Yep that'll do it.

Transactions in Grails are by default handled at a Service method level. If the method returns normally then the transaction will be committed, if a RuntimeException is thrown the transaction will be rolled back.

Note this means even if you use flush:true on while saving an object in the server method the db changes will still be rolled back if you throw a RuntimeException.

For example:

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")
   }                                                           
 }
}

What I'm not 100% clear on with Grails is what happens if a checked exception is thrown in straight java/spring world the default behaviour is for the transaction inceptor to commit the transaction, althrough this can be overriden in the config.

Note: there is a caveat, and that is that your db has to support transactions on the tables you are updating. Yes, this is poke at MySQL :)

This also applies to the Domain.withTransaction method.

这篇关于在Grails服务中回滚事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆