好吧,Grails声明式事务中有一点。它说:
grails.transaction.Transactional 注解最早是在 Grails 2.3 中引入的。在 2.3 之前,使用了 Spring 的 @Transactional 注解。
但我似乎无法找出这两个注释之间的主要区别是什么。为什么在以后的版本中没有使用 Spring 的注解?
好吧,Grails声明式事务中有一点。它说:
grails.transaction.Transactional 注解最早是在 Grails 2.3 中引入的。在 2.3 之前,使用了 Spring 的 @Transactional 注解。
但我似乎无法找出这两个注释之间的主要区别是什么。为什么在以后的版本中没有使用 Spring 的注解?
我想解决这个评论“但是,在 2.3 中,团队认为引入一个新注释是一个好主意(我个人不同意),它不仅可以应用于服务,还可以应用于控制器。”</p>
引入可用于控制器和服务的注解从来不是 Grails 团队的主要意图。我们的主要目的是引入一个 AST 转换,它消除了对代理的需求,并且比 Spring 的 @Transactional 性能更好。Grails 的 @Transactional 将处理事务的必要逻辑直接连接到字节码中,并且不需要代理,因此我们觉得它比 Spring 的版本更好。
它也适用于控制器的事实仅仅是我们发现的上述情况的副作用。话虽如此,根据我们的经验,太多的 Grails 用户在使用控制器时没有正确划分他们的事务边界。如果您将控制器操作标记为只读,则 Hibernate 不需要对您在该操作范围内执行的任何查询执行脏检查。这极大地提高了 Grails 应用程序的性能,并且可能是一件好事。
我们绝对鼓励将逻辑分离到服务中,但是如果您考虑以下简单的示例:
@Transactional(readOnly=true)
def show(Long id) {
respond Foo.get(id)
}
为这种微不足道的操作引入服务是过大的,但如果您不使用只读事务划分查询,那么 Hibernate 会对实例执行脏检查,这会损害性能。
22/02/16 更新:从 Grails 3.1 开始,Spring 版本被认为已弃用,默认情况下被禁用(如果需要,您仍然可以重新启用)
与 Grails 2.3 版本的注释的另一个区别是,如果您从同一服务上的方法 A 调用方法 B,则方法 B 上的事务属性将被兑现。使用 Spring 注释,它不会被兑现,因为您绕过了应用事务的动态代理。
def methodA() {
methodB()
}
@Transactional
def methodB() {
...
}
在 2.3 之前,使用 Spring 注释是因为它应用于服务。这只是简单的 Spring bean。然而,在 2.3 中,团队认为引入一个新的注释是一个好主意(我个人不同意),它不仅可以应用于服务,还可以应用于控制器。不同之处在于 Grails 2.3 版本的注解在 Grails 控制器的概念中做了很多 AST 转换魔法。
希望有帮助。
更新
从功能上讲,当应用于服务时,注释的 Grails 版本与 Spring 版本相同。虽然它的效率稍高一些,因为它是在编译时应用于您的代码的 AST 转换,而不是在运行时应用的代理。
为什么在以后的版本中没有使用 spring 的注解?
您仍然可以使用 Spring 注释。Grails 版本更灵活,性能更高,因为我们可以在编译时构建很多逻辑,但 Spring 版本仍然存在,并且仍然像以前一样运行。
@PrakashJoshi 说:
因此,当您从操作调用服务方法时会发生什么,而该操作又具有其他事务属性。它是否被被调用方法的事务行为覆盖???
这取决于您将事务传播行为设置为什么(可在注释上设置)。PROPAGATION_REQUIRED(默认)将继续一个现有的,但 PROPAGATION_NEW 将启动一个新的,暂停当前的。
你仍然可以使用 spring 注解,但是 grails 版本更快并且更了解框架。
我强烈建议您使用 grails 版本。