Число транзакций при внутреннем вызове метода в Spring‑бине

При обычном proxy-based управлении Spring новая транзакция не откроется: b() не помечен @Transactional, а внутренний вызов a() обходит proxy. Аннотация a() не перехватывается.

Короткий ответ

Что ответить на собеседовании

При обычном proxy-based управлении Spring новая транзакция не откроется: b() не помечен @Transactional, а внутренний вызов a() обходит proxy. Аннотация a() не перехватывается.

Подробный разбор

Ответ с пояснениями

Условие

В Spring‑бине MyService метод a() помечен аннотацией @Transactional, а метод b() напрямую вызывает a(). При этом b() вызывается через внедрённый бин. Сколько транзакций будет открыто в результате такого вызова и почему?

@Component
public class MyService {

    @Transactional
    public void a() {
        // somecode
    }

    public void b() {
        // somecode
        a();
    }
}

Ответ

При обычном proxy-based управлении Spring новая транзакция не откроется: b() не помечен @Transactional, а внутренний вызов a() обходит proxy. Аннотация a() не перехватывается.

Если вызывающий код уже имеет транзакцию, она может оставаться активной, но показанный вызов не создаёт дополнительную. Решение — вынести транзакционный метод в другой bean, вызывать через управляемую границу или использовать программный TransactionTemplate. При AspectJ weaving поведение отличается, поэтому вывод относится именно к стандартной proxy-модели.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее