Spring @Transactional does not work when I call a method inside of it. How can I slove it?
You need to put the @Transactional
annotation above the nestedTransaction()
method as well for the transaction to commit. Also, the propagation = Propagation.REQUIRED
property is default, so you don't need to specify it.
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
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.
The Old "@Transactional from within the same class" Situation
By reading your question it's not really clear where you are stuck, so I am going to briefly list what is needed to get AspectJ intercept your @Transactional
methods.
<tx:annotation-driven mode="aspectj"/>
in your Spring configuration file.<context:load-time-weaver/>
as well in your Spring configuration file.- An aop.xml located in the META-INF folder directly in your classpath. The format of this is also explained here. It should contain an aspect definition for that handles the
@Transactional
annotation:<aspect name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
- The weaver element in that same file should also have an include clause that tells it which classes to weave:
<include within="foo.*"/>
aspectjrt.jar
,aspectjweaver.jar
,spring-aspects.jar
andspring-aop.jar
in the classpath- Starting the application using the flag
-javaagent:/path/to/spring-instrument.jar
(or spring-agent, as it is called in earlier releases)
The final step may not be necessary. It is a really simple class that enables using the InstrumentationLoadTimeWeaver
, but if not available Spring will try to use another load time weaver. I have never tried that, though.
Now, if you think you have fulfilled all steps and still are having problems, I can recommend enabling some options on the weaver (defined in aop.xml):
<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
This makes the weaver output a bunch of information what is being weaved. If you see classes being weaved, you can look for your TestClass
there. Then you at least have a starting point to continue troubleshooting.
Regarding your second edit, "It's almost like the weaving isn't happening fast enough to be woven before the class tries to execute.", the answer is yes, this can happen. I experienced a situation like this before.
I am a little rusty on the specifics, but basically it is something in the lines that Spring will not be able to weave classes that are loaded before the application context is being created. How are you creating your application context? If you are doing it programatically, and that class has a direct reference to TestClass
, then this problem could occur, since TestClass
will be loaded too early.
Unfortunately, I have found that debugging AspectJ is hell.
Related Topics
Mapstruct: Map List of Objects, When Object Is Mapped from Two Objects
How to Get Multiple Columns from Table Using Jpa
How to Update Thousands of Records into MySQL Db in Milliseconds
How to Valid @Requestheader in Spring Boot
Update Objects in One List Based on Values from Second One Using Streams
How to Convert Date Which I Got from Firebase Server as Am Getting Error Date
How to Put a Scanner Input into an Array... for Example a Couple of Numbers
Jackson @Jsonproperty Not Working If Property Name Not Equal Field Name
Testing @Postconstruct With Mockito
Java: How to Ask User If He/She Wants to Continue Program
Remove Duplicate Values from Hashmap in Java
How to Subtract a Constant Value from All Elements of an Array
How to Open a .Dat File in Java Program
String.Replaceall Single Backslashes With Double Backslashes
Why Is My Spring @Autowired Field Null
How to Solve the "Failed to Lazily Initialize a Collection of Role" Hibernate Exception