From the Spring reference 2.5:
When using proxies, the
@Transactional
annotation should only be applied to
methods with public visibility. If you do annotate protected, private or
package-visible methods with the@Transactional
annotation, no error will
be raised, but the annotated method will not exhibit the configured transactional
settings.
So Spring ignores @Transactional
annotation on non-public methods.
Also,
In proxy mode (which is the default), only ‘external’ method calls coming in
through the proxy will be intercepted. This means that ‘self-invocation’,
i.e. a method within the target object calling some other method of the target
object, won’t lead to an actual transaction at runtime even if the invoked
method is marked with@Transactional
!
So even if you make your method public
, calling it from within a method of same class will not start a new transaction.
You can use aspectj
mode in transaction settings so that the transaction related code is weaved in the class and no proxy is created at runtime.
See the reference document for more details.
Another possible way of doing this is fetching the spring proxy of the class in the class itself and call methods on it rather than this
:
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class SomeService {
@Autowired
private ApplicationContext applicationContext;
private SomeService getSpringProxy() {
return applicationContext.getBean(this.getClass());
}
private void doSomeAndThenMore() {
// instead of
// this.doSometingPublicly();
// do the following to run in transaction
getSpringProxy().doSometingPublicly();
}
public void doSometingPublicly() {
//do some transactional stuff here
}
}