Transaction Pitfalls

1. Not Managed by Spring

Common Causes:

  1. Class not scanned by Spring container (missing @Component, @Service and other annotations)
  2. Configuration file not correctly configured with scanning path
  3. Improper method invocation (same-class internal calls)
  4. Instantiating objects with new keyword

Solutions:

  1. Ensure class is correctly annotated and within Spring scanning path
  2. Use @Autowired to get Bean instance, avoid direct new
  3. For same-class method calls, extract transaction method to another Bean

2. Transaction Manager Not Started

In Spring Boot applications, transaction managers are automatically configured:

  • When spring-boot-starter-jdbc or spring-boot-starter-data-jpa dependency is added
  • Spring Boot automatically creates DataSourceTransactionManager instance

3. Improper Transaction Method Modifiers

Problem with final methods:

  • final methods cannot be overridden
  • Spring’s dynamic proxy cannot generate proxy for final methods

Problem with static methods:

  • static methods belong to class level
  • Spring’s transaction management is based on instance proxies, cannot work on static methods

Solution:

  • Avoid using final or static modifiers on methods that need transaction management

4. Internal Calls Within Same Class

Spring transactions are implemented through proxy mechanism. Internal calls within the same class bypass the proxy.

Solutions:

  1. Split class (recommended): Put transaction methods into another Service
  2. Self-injection: Inject self instance into the class
  3. Use AopContext: Get current proxy object through AopContext
// Self-injection method
@Service
public class SomeService {
    @Autowired
    private SomeService self;

    public void methodA() {
        self.methodB();  // Call through proxy
    }

    @Transactional
    public void methodB() {
        // Business logic
    }
}