繁体   English   中英

在事务控制器动作内部执行事务服务调用

[英]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()操作。 但不确定我应该使用哪一个。

您可以使用两种方法。

firstServicesecondService引发异常时,清单1将回滚控制器事务。

在上市#2(我希望createAndSave的方法combinedService与被注解@Transactional )如果将回滚事务createAndSave抛出异常。 使用此方法的最大好处是,该服务方法在理论上可在其他控制器中重用。

@Transactional的关键点之一是要考虑两个单独的概念,每个概念都有自己的范围和生命周期:

  1. 持久性环境
  2. 数据库事务

事务注释本身定义了单个数据库事务的范围。 数据库事务在持久性上下文的范围内发生。 您的代码:

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM