关于Grails服务的一些问题

时间:2011-12-02 03:41:51

标签: spring grails service transactions transactional

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

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

  2. 我可以在班级而不是@Transactional上使用static transactional = true注释吗?是否可以将@Transactional(readOnly = true)置于我希望他们从DB读取(查询,查找)数据的某些方法?

  3. 事务继承怎么样?我的意思是,如果父服务配置为static transactional = true,并且子服务有自己的@Transactional注释(在类上)和一些@Transactional(readOnly = true)(在某些方法上),如果我从孩子的父母那里打电话给一个方法?

  4. 事务是否适用于抽象服务?因为我知道,使用抽象服务我们无法初始化它的bean,也许在启动应用程序时,Grails上下文中存在一些差异。

1 个答案:

答案 0 :(得分:7)

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

对于问题#1,是的 - Spring / Hibernate集成确保在提交之前发生刷新。因此,对save()delete()的调用将被刷新,并且无需向其中添加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-outcome-td3619420.html