Differences between the Grails @Transactional vs.

2019-03-10 06:59发布

Well there was a point in the Grails Declarative Transactions. It said:

The grails.transaction.Transactional annotation was first introduced in Grails 2.3. Prior to 2.3, Spring's @Transactional annotation was used.

But I can't seem to find out what the main difference between those two annotations is. Why was the Spring's annotation not used in future releases?

6条回答
Fickle 薄情
2楼-- · 2019-03-10 07:13

Why was the the spring's annotation not used in future releases ??

You can still use the Spring annotation. The Grails version is more flexible and more performant because we can rig up a lot of the logic at compile time, but the Spring version is still there and still behaves as it did.

查看更多
\"骚年 ilove
3楼-- · 2019-03-10 07:14

@PrakashJoshi said:

So what happens when you invoke service method from the action, which in turn has other transactional property. Is it overwritten by the the called method's transactional behavior ???

It depends on what you have your transactional propagation behavior set to (settable on the annotation). PROPAGATION_REQUIRED (default) will continue an existing one, but PROPAGATION_NEW will start a new one, suspending the current one.

查看更多
乱世女痞
4楼-- · 2019-03-10 07:20

Another difference with the Grails 2.3 version of the annotation is if you call method B from method A on the same service, the transactional attribute on method B will be honored. With the Spring annotation it will not be honored because you bypass the dynamic proxy where transactions are applied.

def methodA() {
    methodB()
}

@Transactional
def methodB() {
    ...
}
查看更多
走好不送
5楼-- · 2019-03-10 07:22

You can still use the spring annotation, but the grails version is faster and more aware of the framework.

I strongly suggest you to use the grails version.

查看更多
我只想做你的唯一
6楼-- · 2019-03-10 07:23

Prior to 2.3 the Spring annotation was used because it was applied to Services. Which are just simple Spring beans. However, in 2.3 the team felt it was a good idea (I disagree personally) to introduce a new annotation which could be applied not only to Services but also to Controllers. The difference is that the Grails 2.3 version of the annotation does a lot of AST transformation magic to work within the concept of a Grails controller.

Hope that helps.

Update

Functionally speaking, when applied to Services the Grails verson of the annotation is identical to the Spring version. Though it's slightly more efficient since it's an AST transformation applied to your code at compile time and not a proxy applied at runtime.

查看更多
家丑人穷心不美
7楼-- · 2019-03-10 07:31

I would like to address this comment "However, in 2.3 the team felt it was a good idea (I disagree personally) to introduce a new annotation which could be applied not only to Services but also to Controllers.”

It was never the primary intention of the Grails team to introduce an annotation that could be used on both controllers and services. Our primary intention was to introduce an AST transform that eliminated the need for a proxy and performed better than Spring’s @Transactional. Grails’ @Transactional wires the necessary logic for dealing with transactions directly into the byte code and doesn’t need a proxy hence why we feel it is better than Spring’s version.

The fact that it also works on controllers is merely a side effect of the above that we discovered. Having said that in our experience too many Grails users do not correctly demarcate their transactional boundaries when using controllers. If you mark a controller action as being read-only then Hibernate does not need to perform dirty checking for any queries you do within the scope the action. This greatly improves performance of Grails applications and can very much be a good thing.

We absolutely encourage separation of logic into services, but if you consider the following trivial example:

  @Transactional(readOnly=true)
  def show(Long id) {
       respond Foo.get(id)
  }

It is overkill to introduce a service for such a trivial action, but if you don’t demarcate the query with a read-only transaction then Hibernate performs a dirty check on the instance which hurts performance.

Update 22/02/16: As of Grails 3.1 the Spring version is considered deprecated and is disabled by default (you can still re-enable if necessary)

查看更多
登录 后发表回答