Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between the Grails @Transactional vs. the Spring @Transactional annotations

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?

like image 989
haedes Avatar asked May 13 '14 09:05

haedes


People also ask

What is the difference between Spring transaction and hibernate transaction?

Hibernate deals with database specific transactions, whereas spring provides a general transaction management service. @Transactional is a nice way of configuring transaction management behaviour.

Why applying Spring @transactional annotation on the concrete class or its methods is recommended rather than on interface?

Spring's recommendation is that you annotate the concrete implementations instead of an interface. It's not incorrect to use the annotation on an interface, it's just possible to misuse that feature and inadvertently bypass your @Transaction declaration.

What is the difference between defining @transactional on class vs method?

The @Transactional annotation on the class level will be applied to every method in the class. However, when a method is annotated with @Transactional (like, updateFoo(Foo foo) ) this will take precedence over the transactional settings defined at the class level. More info: Transaction management in Spring.

What is @transactional Spring annotation?

The @Transactional annotation is the metadata that specifies the semantics of the transactions on a method. We have two ways to rollback a transaction: declarative and programmatic. In the declarative approach, we annotate the methods with the @Transactional annotation.


2 Answers

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)

like image 132
Graeme Rocher Avatar answered Sep 17 '22 13:09

Graeme Rocher


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() {
    ...
}
like image 37
rlovtang Avatar answered Sep 20 '22 13:09

rlovtang