A `@Transactional` method is `private` or `final`, or the class is instantiated with `new`. Is a transaction started?
basicNo. Declarative transactions are applied by a proxy around a Spring bean. The proxy only intercepts calls arriving through it to methods it can override, so new-created objects, private, and final methods (CGLIB cannot override them) get no transaction and fail silently.
- Annotate public methods on beans; since Spring 6, protected and package-private methods are also supported with class-based (CGLIB) proxies.
- Check with
TransactionSynchronizationManager.isActualTransactionActive()or by loggingorg.springframework.transactionat DEBUG. - Put
@Transactionalon the service layer, not controllers or repository interfaces' callers' internals.
- Does
@Transactionalon an interface method work? With JDK proxies yes; with CGLIB class proxies it is honoured in current Spring, but annotate the class to be safe. - Does a Spring Data repository need
@Transactional? Its CRUD methods are already transactional (SimpleJpaRepository).