Self-invocation bypasses the proxy, preventing transaction management.
In Spring, @Transactional uses proxies to manage transactions. If a method in the same class calls another @Transactional method, the internal call bypasses the proxy, and transaction management is not applied. To solve this, restructure the code to call the method from an external class or use AOP to handle the transaction boundary.
Additional Notes
Why can self-invocation of a @Transactional method fail?