当服务中抛出RuntimeException时,我使用Grail的回滚功能将所有服务更新为事务性。在大多数情况下,我都这样做:
def domain = new Domain(field: field) if (!domain.save()) { throw new RuntimeException() }
无论如何,我想验证这是否确实会回滚事务……这让我开始思考是否在这一点上已经提交了。此外,如果没有,设置flush:true会改变这一点吗?我对Spring / Hibernate如何完成所有这些工作不是很熟悉:)
是的,那样做。
默认情况下,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方法。
Domain.withTransaction