@Transactional, @Async, @Cacheable, @Retryable работают через прокси (JDK dynamic proxy на интерфейсах, CGLIB на классах). Аннотация срабатывает, только когда вызов проходит через прокси, то есть приходит снаружи бина.Вызов соседнего метода через this идёт мимо прокси и аннотация молча игнорируется:
@Service
public class OrderService {
public void handle() {
save(); // this.save() — мимо прокси
}
@Transactional
public void save() { // транзакции здесь НЕ будет
...
}
}
Сюда же: @Transactional на private, final и static методах не работает — CGLIB не может их переопределить.
🔹 Лечится так:
→ вынести метод в отдельный бин (самый чистый вариант);
→ self-injection (инъекция самого себя и вызов через него);
→ ((OrderService) AopContext.currentProxy()).save() (требует exposeProxy = true);
→ TransactionTemplate для программного управления.
Симптом всегда один «аннотация висит, а эффекта нет». Первым делом проверяй, не self-invocation ли это.
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#CoreJava