Grails 如果一个域保存失败,如何回滚所有事务?

Grails 如果一个域保存失败,如何回滚所有事务?,grails,transactions,gorm,Grails,Transactions,Gorm,我想知道是否可以回滚多个更改 比如说 假设在控制器内,我有三个域先后保存 domain1.save(flush:true) domain2.save(flush:true) domain3.save(flush:true) 现在我希望行为是这样的,如果这三个保存中的任何一个失败,那么成功的保存也应该回滚,即我希望所有这三个保存都构成一个事务。我想知道在grails中是否有这样做的方法?我找到了withTransaction,但它似乎与特定域关联。谢谢寻求帮助。withTransaction与调

我想知道是否可以回滚多个更改

比如说

假设在控制器内,我有三个域先后保存

domain1.save(flush:true)
domain2.save(flush:true)
domain3.save(flush:true)

现在我希望行为是这样的,如果这三个保存中的任何一个失败,那么成功的保存也应该回滚,即我希望所有这三个保存都构成一个事务。我想知道在grails中是否有这样做的方法?我找到了withTransaction,但它似乎与特定域关联。谢谢寻求帮助。

withTransaction
与调用它的域类无关,但它有点像黑客,因为它允许您在控制器中执行事务持久化之类的愚蠢操作。控制器应该关注HTTP相关的东西,并将实际工作委托给服务,这些服务在默认情况下是方便的事务性的,除非您为特定服务禁用它

将所有数据库更新和业务逻辑移动到服务中,并使您的控制器保持轻量级,专注于提取请求参数和进行数据绑定(例如,通过
int foo=params.int('foo')将字符串“12453”转换为int 12453)
,并使用该数据调用服务方法,然后将其返回值传递给要呈现的视图。控制器应该是路由器


如果需要,您可以使用
@Transactional
注释来自定义整个服务或每个方法的事务工作方式,但默认情况下,即使没有任何注释,服务也是事务性的。您可以在一个方法中做任意多的工作,所有工作都将成功或全部回滚。我甚至只做一次更新/删除/插入在事务性方法中,可以简化以后在不考虑事务的情况下根据需要使事情变得更复杂。如果所有数据库更改都是事务性的,通常情况下,事情会运行得更好。

Burt,感谢您的解释。这很有帮助。 MVC变成了MVC。 但请再澄清一点: 我曾经了解到,即使没有我对.save()的调用,控制器也会希望将更新的类(在绑定新参数后)保存在自己的上。 这将如何干扰中间调用的服务中已处理/保存的类? 或者控制器仅从字符串创建一个整数,并将更正后的参数进一步传递给服务,以便在服务中完成所有工作,就像控制器在MVC世界早期所做的那样

编辑和后期反应:
很抱歉没有足够的评论声誉

谢谢!伯特。还有一点需要澄清。在上面的示例中,这三个域是独立的。那么,服务类是否检测到这一点,并确保所有域都成功或没有成功。是的,只要它们使用相同的
数据源
,它们将使用相同的Hibernate会话和JDBC Connect如果域混合使用数据源,则需要使用两阶段提交,但如果使用插件,这很容易。我在网上有一个讨论Grails中事务的演讲,大约45分钟:这不应该是答案