Common Scenarios Where Spring @Transactional Fails and How to Fix Them

This article outlines common situations that cause Spring @Transactional to fail—such as non‑public methods, internal method calls, unmanaged beans, non‑runtime exceptions, silent catches, incorrect propagation settings, and unsupported MySQL storage engines—and provides practical solutions to ensure transaction reliability.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Common Scenarios Where Spring @Transactional Fails and How to Fix Them

In real‑world projects, developers often rely on Spring transactions to guarantee data consistency across multiple tables. However, various subtle mistakes can cause the @Transactional annotation to become ineffective, leading to data anomalies and wasted debugging time.

1. @Transactional on Non‑Public Methods

Spring creates proxies for beans, and only public methods are intercepted. If a protected, private, or package‑private method is annotated, the transaction settings are ignored. The fix is to keep the method public or enable AspectJ weaving.

2. Bean Not Managed by the Spring Container

If the class containing @Transactional is not a Spring bean (e.g., missing @Service), the annotation has no effect. Ensure the class is registered in the container.

@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ClassService classService;

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insertClassByException(StudentDo studentDo) throws CustomException {
        studentMapper.insertStudent(studentDo);
        throw new CustomException();
    }
}

3. Internal Method Calls Bypass the Proxy

When a method in the same class calls another @Transactional method, the call is made directly (via this) and the proxy is bypassed, so the transaction does not start.

Solution: invoke the method through the current proxy.

public void insertClass(ClassDo classDo) throws CustomException {
    // ((ClassServiceImpl)AopContext.currentProxy()).insertClassByException(classDo);
    ((ClassServiceImpl)AopContext.currentProxy()).insertClassByException(classDo);
}

Also add @EnableAspectJAutoProxy(exposeProxy = true) to the configuration class.

4. Throwing Non‑RuntimeException

By default, Spring rolls back only on unchecked exceptions. Throwing a checked exception (e.g., Exception) will not trigger a rollback unless rollbackFor is specified.

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void insertClassByException(ClassDo classDo) throws Exception {
    classMapper.insertClass(classDo);
    throw new Exception();
}

5. Catching Exceptions Without Rethrowing

If a transactional method catches an exception and does not rethrow it (or throw a RuntimeException), the transaction will be committed despite the error.

try {
    int i = 1 / 0;
} catch (Exception e) {
    e.printStackTrace();
    throw new RuntimeException(); // rethrow to trigger rollback
}

6. Incorrect Propagation Setting

Using Propagation.NOT_SUPPORTED disables transaction support for the method, causing all database operations to run outside a transaction.

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void insertClassByException(ClassDo classDo) {
    // operations will not be transactional
}

7. MySQL Storage Engine Not Supporting Transactions

If the MySQL table uses the MyISAM engine, transactions are ignored because MyISAM does not support them. Switch to InnoDB (the default from MySQL 5.5 onward) to enable transactional behavior.

By addressing these seven pitfalls—ensuring public methods, proper bean registration, proxy‑based internal calls, appropriate exception handling, correct propagation, and a transactional‑compatible storage engine—developers can reliably use Spring transactions in backend applications.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendjavatransactionaopspringExceptiontransactional
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.