Sobes.tech
Назад к вопросам
Junior — Middle
51

Какие шаги необходимо выполнить, чтобы аннотация @Transactional начала правильно функционировать в вашем приложении?

Компании, где спрашивали
ВТБВТБ

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

@Transactional работает не “сама по себе”, а через proxy/Spring AOP, поэтому нужно чтобы вызовы шли через Spring-бин. Также требуется настроенный transaction manager и подходящий источник данных. Если нарушить эти условия, аннотация может просто не сработать или сработать не так, как ожидается.

Определение:

@Transactional — это аннотация Spring для объявления границ транзакции вокруг метода или класса. Spring открывает транзакцию перед выполнением метода, а после успешного завершения коммитит её; при исключении — откатывает, если исключение подходит под правила rollback. Для корректной работы нужна инфраструктура Spring, которая умеет создавать прокси и управлять транзакциями.

Пример использования:

@Service
public class OrderService {

    private final OrderRepository orderRepository;
    private final PaymentRepository paymentRepository;

    public OrderService(OrderRepository orderRepository, PaymentRepository paymentRepository) {
        this.orderRepository = orderRepository;
        this.paymentRepository = paymentRepository;
    }

    @Transactional
    public void createOrder(Order order, Payment payment) {
        orderRepository.save(order);
        paymentRepository.save(payment);

        if (payment.isRejected()) {
            throw new IllegalStateException("Payment failed");
        }
    }
}

Пояснение кода:

В этом примере метод createOrder() выполняется в одной транзакции. Если оба save() отработают успешно, Spring закоммитит изменения в базе. Если на этапе проверки платежа выбросится исключение, транзакция будет откатена, и данные не сохранятся частично.

Чтобы это заработало в приложении, обычно нужно выполнить такие шаги:

  1. Подключить Spring-стек, который поддерживает транзакции.
  2. Настроить источник данных и transactionManager.
  3. Пометить класс сервиса как Spring-бин, например через @Service.
  4. Ставить @Transactional на публичные методы, которые должны выполняться в транзакции.
  5. Вызывать этот метод извне бина, а не через self-invocation внутри того же класса.
  6. Убедиться, что исключения действительно приводят к rollback по правилам Spring.

Ключевые моменты:

  • @Transactional работает через прокси Spring, а не напрямую на методе.
  • Метод должен вызываться через Spring-бин, иначе транзакция может не открыться.
  • Нужен настроенный transactionManager и подключенный источник данных.
  • Чаще всего аннотацию ставят на public-методы сервисного слоя.
  • Вызов метода изнутри того же класса обходится без прокси и ломает транзакционность.
  • По умолчанию rollback обычно происходит на RuntimeException и Error, а не на checked exception.