Приведёт ли необработанное исключение в методе с @Transactional к откату транзакции?

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

Ответ

Да, по умолчанию транзакция откатится (rollback), если метод, аннотированный @Transactional, завершится необработанным исключением типа RuntimeException или Error.

Настройка поведения отката:

import org.springframework.transaction.annotation.Transactional;

// 1. Откат для всех исключений (включая checked)
@Transactional(rollbackFor = Exception.class)
public void saveData() throws IOException {
    // Вызов метода, который может выбросить IOException (checked exception)
}

// 2. БЕЗ отката для определённых исключений
@Transactional(noRollbackFor = {IllegalArgumentException.class, NullPointerException.class})
public void validateAndProcess() {
    // При IllegalArgumentException транзакция НЕ откатится
}

Критически важные нюансы:

  • Видимость метода: Механизм @Transactional работает через Spring AOP (прокси), поэтому он применяется только к public-методам.
  • Self-invocation: Вызов @Transactional-метода из другого метода того же класса не будет идти через прокси, и аннотация не сработает. Решение — использовать инъекцию самого бина или AspectJ.
  • Момент отката: Откат происходит при выходе из метода с исключением. Если исключение перехвачено и не проброшено дальше — отката не будет.