[英]grails transactional service calls inside transactional controller action
这两个控制器动作之间有什么区别:
@Transactional
def save(SomeDomain someDomain) {
someDomain.someProperty = firstService.createAndSaveSomething(params) //transactional
someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional
someDomain.save(flush: true)
}
和
def save(SomeDomain someDomain) {
combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls
}
我的目的是在事务失败时回退整个save()操作。 但不确定我应该使用哪一个。
您可以使用两种方法。
当firstService
或secondService
引发异常时,清单1将回滚控制器事务。
在上市#2(我希望createAndSave
的方法combinedService
与被注解@Transactional
)如果将回滚事务createAndSave
抛出异常。 使用此方法的最大好处是,该服务方法在理论上可在其他控制器中重用。
@Transactional
的关键点之一是要考虑两个单独的概念,每个概念都有自己的范围和生命周期:
事务注释本身定义了单个数据库事务的范围。 数据库事务在持久性上下文的范围内发生。 您的代码:
@Transactional
def save(SomeDomain someDomain) {
someDomain.someProperty = firstService.createAndSaveSomething(params) //transactional
someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional
someDomain.save(flush: true)
}
持久性上下文在JPA中是EntityManager,使用Hibernate Session在内部实现(当使用Hibernate作为持久性提供程序时)。 您的代码:
def save(SomeDomain someDomain) {
combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls
}
注意:持久性上下文只是一个同步器对象,该对象跟踪一组有限的Java对象的状态,并确保最终将这些对象上的更改持久化回到数据库中。
结论:声明式事务管理机制( @Transactional
)非常强大,但很容易被滥用或错误配置。
在机制无法正常工作或无法正常工作的情况下进行故障排除时,了解其内部工作方式将很有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.