Будет ли работать аннотация @Transactional в Spring для приватного метода?

«Будет ли работать аннотация @Transactional в Spring для приватного метода?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, не будет. Spring управляет транзакциями через AOP-прокси (или AspectJ). Прокси могут перехватывать вызовы только публичных методов.

Почему это не работает:

  1. Ограничение прокси: Spring создает прокси вокруг класса. Вызов приватного метода происходит напрямую, минуя прокси, поэтому аспект транзакционности не применяется.
  2. Принцип ООП: Приватные методы не видны извне класса, включая прокси-объект.

Некорректный пример:

@Service
public class TransactionService {

    @Transactional // НЕ БУДЕТ РАБОТАТЬ
    private void updateData() {
        // Логика с доступом к БД
    }

    public void publicMethod() {
        updateData(); // Вызов приватного метода -> транзакции НЕТ
    }
}

Решение:

  • Делайте методы с @Transactional как минимум package-visible (уровень доступа по умолчанию) или public.
  • Выносите транзакционную логику в отдельный публичный метод.
  • Используйте режим mode = AdviceMode.ASPECTJ для weaving'а на уровне байт-кода (позволяет обойти ограничение, но требует дополнительной настройки).

Вывод: @Transactional применима только к методам с видимостью, позволяющей перехват вызова через прокси.