Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Transactional class vs method precedence rules

Spring says abuot @Transactional

The most derived location takes precedence when evaluating the transactional settings for a method.

Does this mean the annotation on method completely overrides annotation from class or does the omitted attributes (so defaults) does not count?

E.g.

@Transactional(isolation=Isolation.SERIALIZABLE)
public class MyService {

    @Transactional(readOnly=true)
    public void method() {
       ...
    }
}

So what is the isolation settings of the method? Is this Isolation.DEFAULT because this is the default so it implicitly overrides Isolation.SERIALIZABLE or is it Isolation.SERIALIZABLE because none was explicitly specified on method annotation?

like image 464
Lukasz Lichota Avatar asked May 22 '13 07:05

Lukasz Lichota


People also ask

What happens if one @transactional annotated method is calling another @transactional annotated method on the same object instance?

If you call a method with a @Transactional annotation from a method with @Transactional within the same instance, then the called methods transactional behavior will not have any impact on the transaction.

Can we use @transactional on class?

2.2. How to Use @Transactional. We can put the annotation on definitions of interfaces, classes, or directly on methods. They override each other according to the priority order; from lowest to highest we have: interface, superclass, class, interface method, superclass method, and class method.

When @transactional is used on top of a class?

@Transactional can be used on top of class or method, in classes or interfaces. If used on top of class, it applies to all public methods in this class.

Can @transactional annotation only be used at class level?

Annotation Type Transactional. Describes a transaction attribute on an individual method or on a class. When this annotation is declared at the class level, it applies as a default to all methods of the declaring class and its subclasses.


1 Answers

The annotation at the method level completely overrides the annotation at the type-level. Any kind of hierarchy is not quite possible here. Let me explain a little more. There is no way to find out if a value was specified by the user for a specific attribute, or if a default value is being returned when you read the attributes of an annotation. So, Spring, or anybody else, cannot determine whether a specific attribute was overridden, or if a default value is being used. So, there is no way to make a decision based on the presence or absence of an attribute. For that reason, whenever you override any annotation (that is, specify it with finer granularity), you need to specify all the required attributes. So, in your case, the Isolation.DEFAULT will be the isolation applied.

However, as a aside, suppose you have your own custom annotation that specifies an empty-string as the default value for some attribute. In that case, if your class-level annotation specifies a non-empty string for that attribute, and your method-level annotation doesn't specify any value (thus using the default value: the empty-string), you could infer that the attribute-value from the class-level annotation should be used. That is, not allowing the default-value in the method-level annotation to override the user-specified value at the class-level. In any such scenario, you have to be sure that the default-value doesn't represent a valid attribute-value. In the case of the @Transactional annotations, Isolation.DEFAULT does represent a valid value and it may have been explicitly be specified by the user.

like image 106
Bhashit Parikh Avatar answered Sep 18 '22 16:09

Bhashit Parikh