Problem:
In Spring, attempting to invoke a method annotated with @Transaction from within the same class can result in an ineffective transaction.
Code Example:
public class UserService { @Transactional public boolean addUser(String userName, String password) { // ... } public boolean addUsers(List<User> users) { for (User user : users) { addUser(user.getUserName, user.getPassword); } } }
Understanding the Issue:
This issue arises due to limitations in Spring AOP's dynamic object handling and the use of cglib. Spring's default transaction handling mechanism uses dynamic proxies created with cglib, which can cause inconsistencies when calling a transactional method from within the same class.
Solution:
Using AspectJ for Transaction Handling:
To resolve this, you can configure Spring to use AspectJ for handling transactions. This involves:
Setting the mode to aspectj in tx:annotation-driven:
<tx:annotation-driven mode="aspectj"/>
Adding the following bean configuration (only for Spring versions below 3.0):
<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf"> <property name="transactionManager" ref="transactionManager"/> </bean>
Refactoring:
An alternative solution is to refactor your code. Instead of invoking the transactional method from within the same class, consider creating separate classes for user handling and processing to enable default transaction handling using Spring AOP.
The above is the detailed content of Why Do @Transactional Methods Fail When Self-Invoked Within the Same Class in Spring?. For more information, please follow other related articles on the PHP Chinese website!