Grails @Transactional与Spring @Transactional注释之间的差异

hae*_*des 16 grails annotations transactional grails-2.3 grails-2.5

那么Grails Declarative Transactions就有一点了.它说:

grails.transaction.Transactional注释最初是在Grails 2.3中引入的.在2.3之前,使用了Spring的@Transactional注释.

但我似乎无法找出这两个注释之间的主要区别是什么.为什么未来的版本中没有使用Spring的注释?

Gra*_*her 29

我想谈谈这个评论"然而,在2.3中,团队认为引入一个新的注释是一个好主意(我个人不同意),它不仅可以应用于服务,还可以应用于控制器."

Grails团队的主要目的永远不是引入可用于控制器和服务的注释.我们的主要目的是引入一个AST转换,消除了对代理的需求,并且比Spring的@Transactional表现得更好.Grails的@Transactional将处理事务的必要逻辑直接连接到字节代码中,并且不需要代理,因此我们觉得它比Spring的版本好.

它也适用于控制器这一事实仅仅是我们发现的上述副作用.话虽如此,根据我们的经验,太多Grails用户在使用控制器时没有正确划分其事务边界.如果将控制器操作标记为只读,则Hibernate不需要对您在操作范围内执行的任何查询执行脏检查.这极大地提高了Grails应用程序的性能,并且非常有用.

我们绝对鼓励将逻辑分离为服务,但如果您考虑以下简单示例:

  @Transactional(readOnly=true)
  def show(Long id) {
       respond Foo.get(id)
  }
Run Code Online (Sandbox Code Playgroud)

为这样一个简单的操作引入服务实在是太过分了,但如果你没有用只读事务划分查询,那么Hibernate会对实例进行脏检查,从而影响性能.

更新22/02/16:从Grails 3.1开始,Spring版本被认为已弃用,默认情况下已禁用(如有必要,您仍可以重新启用)


rlo*_*ang 16

Grails 2.3版本注释的另一个不同之处在于,如果您在同一服务上调用方法A中的方法B,则方法B上的事务属性将受到尊重.使用Spring注释,它将不会受到尊重,因为您绕过了应用事务的动态代理.

def methodA() {
    methodB()
}

@Transactional
def methodB() {
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 是否有关于此行为的文档,或者这只是您观察到的内容?我观察到了同样的行为. (2认同)

Jos*_*ore 5

在2.3之前,使用了Spring注释,因为它已应用于Services.这只是简单的Spring bean.然而,在2.3中,团队认为引入一个新的注释是一个好主意(我个人不同意),它不仅可以应用于服务,还可以应用于控制器.不同之处在于Grails 2.3版本的注释在Grails控制器的概念中运行了很多AST转换魔术.

希望有所帮助.

更新

从功能上讲,当应用于Services时,注释的Grails verson与Spring版本相同.虽然它的效率略高,因为它是在编译时应用于代码的AST转换,而不是在运行时应用的代理.