If I have a @Transactional annotation on a private method in a Spring bean, does the annotation have any effect?
If the @Transactional annotation is on a public method, it works and opens a transaction.
@Transactional
public class Bean { public void doStuff() { doPrivateStuff(); } @Transactional private void doPrivateStuff() { } } ... Bean bean = (Bean)appContext.getBean("bean"); bean.doStuff();
In Spring, the @Transactional annotation is typically applied to public methods. The reason for this is that the proxy-based mechanism that Spring uses for transaction management works by creating dynamic proxies for the target beans. These proxies are only able to intercept calls to public methods.
If you annotate a private method with @Transactional, the annotation will have no effect, and the method won’t be wrapped in a transactional proxy. As a result, the transactional behavior won’t be applied to the private method, and it will be executed without any transactional support.
In your example:
public class Bean { public void doStuff() { doPrivateStuff(); } @Transactional private void doPrivateStuff() { } }
The @Transactional annotation on doPrivateStuff() will not have any effect when doStuff() is called, as the transactional proxy won’t intercept calls to private methods.
doPrivateStuff()
doStuff()
If you want the transactional behavior to be applied to doPrivateStuff(), you should move the @Transactional annotation to a public method that calls doPrivateStuff(). For example:
public class Bean { @Transactional public void doStuff() { doPrivateStuff(); } private void doPrivateStuff() { } }
In this way, the transactional proxy will intercept the call to the public method, and the transactional behavior will be applied to the entire transactional method, including the private method call.