grails事务性服务调用内部事务控制器操作

时间:2015-08-14 03:47:01

标签: grails service transactions controller

这两个控制器操作之间的区别是什么:

  @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()动作。但不确定我使用哪一个。

2 个答案:

答案 0 :(得分:3)

您可以使用这两种方法。

firstServicesecondService抛出异常时,您的商家信息#1将回滚控制器交易。

在列表#2中(我期望createAndSave的{​​{1}}方法用combinedService注释)如果@Transactional抛出异常,将回滚事务。使用这种方法的一大优点是,这种服务方法在理论上可以在其他控制器中重复使用。

答案 1 :(得分:0)

关于@Transactional def save(SomeDomain someDomain) { someDomain.someProperty = firstService.createAndSaveSomething(params) //transactional someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional someDomain.save(flush: true) } 的一个关键点是,需要考虑两个独立的概念,每个概念都有自己的范围和生命周期:

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

    def save(SomeDomain someDomain) {
            combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls
        }
    

    持久化上下文在JPA中是EntityManager,使用Hibernate Session在内部实现(当使用Hibernate作为持久性提供程序时)。你的代码:

    @Transactional

    注意:持久化上下文只是一个同步器对象,它跟踪一组有限的Java对象的状态,并确保对这些对象的更改最终保留在数据库中。

    结论:声明式事务管理机制(<core-label>)功能非常强大,但可能会被滥用或错误配置。

    在机制完全无法正常工作或以意想不到的方式工作时,了解内部工作原理非常有用。