@Transactional method called from another method doesn't obtain a transaction
It is one of the limitations of Springs AOP. Because the dao bean is in fact a proxy when it is created by spring, it means that calling a method from within the same class will not call the advice (which is the transaction). The same goes for any other pointcut
Can @Transactional method call another @Transactional method without suspending?
As far as i know you can't do it with annotation REQUIRED_NEW.
But spring also support transaction manually with TransactionTemplate, TransactionDefinition.
we can use multiple definitions with just one PlatformTransactionManager.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/support/TransactionTemplate.html
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/TransactionDefinition.html
https://www.baeldung.com/spring-programmatic-transaction-management#4-custom-transaction-configurations
What happens if one @Transactional annotated method is calling another @Transactional annotated method on the same object instance?
If you call method2()
from method1()
within the same class, the @Transactional
annotation of the second method will not have any effect because it is not called through proxy, but directly. Methods are enhanced with transactional behavior only if called through proxy (autowired bean, or some instance injected in any other way).
But generally speaking, if method1()
and method2()
were in different classes, and both were annotated with @Transactional
(so using REQUIRED
propagation), then they would share the same transaction started in method1()
.
Calling @Transactional method from non-transactional method in Spring 4.3
But this code works correctly in Spring 4.3.20. Is this rule actual
for Spring 4.3.20?
Yes. SonarLint is correct. Self-invocation cannot make @Transactional
to take effect. It does not change even in Spring 5. That is how Spring AOP works (refer to docs). Your codes works most probably because you start another transaction inside itemDao
(May be you have another @Transactional
marked on ItemDao#addItems()
).
if I make the second method as package-private, the SonarLint warning
disappears... Why?
Don't know why. Maybe it is a bug. As mentioned in this rule , it should give you warning when mark @Transactional
in private method.
Call @Transactional annotated method from another @Transactional annotated method
It depends on the txType. By default it is REQUIRED. So the first method starts the transaction and the same transaction is used for the call to method2.
Also be careful that a method call inside the same object does not trigger the transaction processing. As typically the transaction handling is handled as proxy that only works when calling an injected other bean. In your example you would not notice a difference though.
A case where this would matter is if method1 is not @Transactional and method2 is. In this case there would be no transaction at all.
When calling a spring Non-Transactional method from a Transactional Method in another instance, does the transaction get propagated?
If there are no @Transactional annotations in B to tell it otherwise, then the b method uses the transaction established in the call to A.methoda. This is normal for Spring, we have components marked transactional that call DAOs that participate in the current transaction without being marked transactional themselves.
If you really want to suspend the current transaction, you can add this annotation to the b method:
@Transactional(propagation = Propagation.NOT_SUPPORTED)
There is a caveat about suspending transactions in the Spring API doc:
NOTE: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to JtaTransactionManager, which requires the javax.transaction.TransactionManager to be made available to it (which is server-specific in standard Java EE).
Spring Boot With @Transactional annotated method, calls other transactional methods and throws an Exception
Make sure that the method annotated with @Transactional
is declared as public
and called by a different class.
A transactional method must be public so that Spring can override it and it must be called from outside the defining class so that the invocation can go through a proxy.
It's one of the common pitfalls when using @Transactional, for more information see https://codete.com/blog/5-common-spring-transactional-pitfalls/
Related Topics
Spark Strutured Streaming Automatically Converts Timestamp to Local Time
How to Handle Simultaneous Key Presses in Java
Method Overload Resolution in Java
What Determines Kafka Consumer Offset
Deciphering Variable Information While Debugging Java
Is It Better Practice to Use String.Format Over String Concatenation in Java
When Are Java Strings Interned
Why Can't We Use '==' to Compare Two Float or Double Numbers
How and Where to Use Static Modifier in Java
Generic Wildcard Types Should Not Be Used in Return Parameters
Differencebetween 'E', 'T', and '' for Java Generics
Using Java to Decrypt Openssl Aes-256-Cbc Using Provided Key and Iv
Use Custom Manifest File and Permission in Unity
How to Find and Kill Running Win-Processes from Within Java