Spring Boot中@Transactional注解未触发回滚问题求助
Hey there, let's break down why your transaction isn't rolling back and fix it step by step.
The Root Cause: Spring AOP Can't Intercept Private Methods
Spring's default transaction management relies on AOP proxies (either JDK dynamic proxies or CGLIB). Here's the key issue:
- JDK proxies only work with public methods defined on interfaces.
- CGLIB proxies create a subclass of your class to handle interception, but they still can't access or override private methods (since private methods aren't inherited).
Your saveAndUpdatepMSTAndRollUpEntries method is private, so Spring's proxy mechanism completely ignores the @Transactional annotation—no transaction is created at all, which means rollback can't happen when an exception is thrown.
Fixes to Get Transaction Rollback Working
1. Make the Method Public (Simplest & Most Common Fix)
This is the go-to solution for most cases:
- Change the method's modifier from
privatetopublic. - Ensure you call this method through the Spring-managed proxy object, not via a direct internal call (e.g., avoid
this.saveAndUpdatepMSTAndRollUpEntries(...)from another method in the same class—this skips the proxy and bypasses transaction logic).
Example modified code:
@Transactional(rollbackOn = Exception.class) public void saveAndUpdatepMSTAndRollUpEntries(pMST newpMSTEntry, pMST existingpMSTEntry, List<sPTrans> sPTranss, List<sPTrans> sPTransUpdatedFlagList) { if(!ObjectUtils.isEmpty(existingpMSTEntry)) databaseService.deleteProcessedpMST(existingpMSTEntry); if(!CollectionUtils.isEmpty(sPTransUpdatedFlagList)) databaseService.saveProcessedsPTransFeedWithUpdatedFlag(sPTransUpdatedFlagList); // Rest of your business logic }
2. Use AspectJ (If You Must Keep the Method Private)
If you absolutely can't change the method to public, you can use AspectJ instead of Spring's default AOP. AspectJ weaves transaction logic directly into your class at compile time or class load time, so it can intercept private methods.
To set this up:
- Add AspectJ dependencies to your build file (Maven example):
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> - Enable AspectJ mode in your transaction configuration:
@Configuration @EnableTransactionManagement(mode = AdviceMode.ASPECTJ) public class TransactionConfig { // Your PlatformTransactionManager bean configuration here } - Configure compile-time weaving (or load-time weaving) based on your build setup.
Additional Checks to Ensure Rollback Works
Once the annotation is being picked up, verify these details:
- Make sure
@EnableTransactionManagementis present on one of your Spring configuration classes (this enables transaction management in the first place). - Confirm you have a valid
PlatformTransactionManagerbean (Spring Boot auto-configures this for most databases, but double-check if you have a custom setup). - Your
rollbackOn = Exception.classis correctly configured—it triggers rollback for all exceptions (checked and unchecked), which is more inclusive than the default behavior (only uncheckedRuntimeExceptionandError).
内容的提问来源于stack exchange,提问作者kaviya .P

