@Transactional public class UserServiceImpl implements UserService { ................... public void method1(){ try{ method2(); }catch(Exception e){ } } public void method2(){ } }
public class UserServiceImpl implements UserService { ................... public void method1(){ try{ method2(); }catch(Exception e){ } } @Transactional public void method2(){ } }
In case1 if any exception occurs it rollback is working, but in case 2 it's not working. Is there any performance issues if I follow the case1?
The @Transactional Annotation With transactions configured, we can now annotate a bean with @Transactional either at the class or method level: @Service @Transactional public class FooService { //... }
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.
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.
The answer your question is no - @Transactional will have no effect if used to annotate private methods. The proxy generator will ignore them. When using proxies, you should apply the @Transactional annotation only to methods with public visibility.
In case 1 @Transactional is applied to every public individual method. Private and Protected methods are Ignored by Spring.
Spring applies the class-level annotation to all public methods of this class that we did not annotate with @Transactional. However, if we put the annotation on a private or protected method, Spring will ignore it without an error.
In case 2 @Transactional is only applied to method2(), not on method1()
Case 1: - Invoking method1() -> a transaction is started. When method1() calls method2() no new transaction is started, because there is already one
Case 2: - Invoking method1() -> no transaction is started. When method1() calls method2() NO new transaction is started. This is because @Transactional does not work when calling a method from within the same class. It would work if you would call method2() from another class.
From the spring reference manual:
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional. Also, the proxy must be fully initialized to provide the expected behaviour so you should not rely on this feature in your initialization code, i.e. @PostConstruct.
@Transactional
on a class applies to each method on the service. It is a shortcut. Typically, you can set @Transactional(readOnly = true)
on a service class, if you know that all methods will access the repository layer. You can then override the behavior with @Transactional
on methods performing changes in your model. Performance issues between 1) and 2) are not known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With