8

我正在使用 Grails Web 应用程序,并且在使用 Grails 服务时遇到了很多奇怪的事情。所以我想问一些关于这个的问题,让我更多地了解 Grails 服务。这对我非常有帮助(也许对其他人也有帮助^_^)。提前致谢。

  1. 如果服务配置为 static transactional = true,它是否会在使用脏的对象调用任何方法后将每个数据更改刷新到 DB 并锁定在 Hibernate 会话中?

  2. 我可以@Transactional在类级别使用注释而不是static transactional = true吗?是否可以使用@Transactional(readOnly = true)一些我只想让他们从数据库中读取(查询、查找)数据的方法?

  3. 事务继承如何?我的意思是,如果父服务已配置static transactional = true,并且子服务有自己的@Transactional注释(在类上)和一些@Transactional(readOnly = true)(在某些方法上),如果我从子服务调用父方法会发生什么?

  4. 事务性是否适用于抽象服务?因为据我所知,使用抽象服务我们无法初始化其 bean,并且可能在启动应用程序时,Grails 上下文存在一些差异。

4

1 回答 1

7

你应该每个问题问一个问题:)

对于问题 #1,是的 - Spring/Hibernate 集成确保在提交之前发生刷新。所以调用save()anddelete()将被刷新,没有必要添加flush: true任何一个。此外,您未调用save()的脏实例也将被刷新,除非您调用discard().

对于#2:服务默认是事务性的,所以transactional = true实际上是多余的——你只需要将它指定为transactional = false. 但是只有在没有@Transactional注释的情况下才会创建自动事务包装器。如果您有一个或多个注释,那么这些注释定义了事务分界。所以默认情况下(即没有注释,也没有transactional属性或transactional = true)所有方法都是事务性的,但是如果您只注释方法的子集,那么只有那些将是事务性的。

通常,当您想要非默认行为时,您会使用注释,即自定义传播、隔离、超时等(或者像在您的示例中一样使其只读)。

您可以在类级别进行注释以使所有方法具有相同的配置,并且可以选择注释单个方法以覆盖类范围的默认值。

对于#3 和#4,适用标准规则(参见#2)。如果子类有注释,那么transactional = true该类或父类中的注释将被忽略,因为通过使用注释,您已经告诉 Grails 您正在自己配置事物。

由于无法实例化抽象服务,因此实际实例化的具体子类将具有来自基类和自身的组合行为。如果一切正常,transactional = true那么它很简单,并且如果您有任何注释,那么它们会定义规则。

调用超类中的方法就像调用当前类中的方法一样。但是,如果您没有考虑 Spring 代理方法的含义,那么这种行为有点违反直觉。当您调用事务方法时,代理会拦截调用并加入活动事务,或者在需要时启动一个新事务,或者在指定 REQUIRES_NEW 时启动一个新事务。但是一旦你进入真正的类并调用另一个方法,你就会绕过代理。因此,如果您使用不同的注释设置调用另一个方法,它们将被忽略。如果您打算这样做,请参阅此邮件列表讨论,了解正在发生的事情以及如何使用它: http: //grails.1312388.n4.nabble.com/non-transactional-service-extends-transactional-service -结果-td3619420.html

于 2011-12-02T04:20:50.873 回答