Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Spring: transaction, spring

Если внутри Spring-транзакции есть операция с БД, затем REST-вызов, а затем ещё одна операция с БД, и последняя операция падает, что произойдёт с REST-вызовом?

Вопрос проверяет понимание границ транзакций и их поведения при внешних вызовах в Spring.

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

REST-вызов уже будет выполнен и не может быть отменён. Spring-транзакции управляют только операциями с базой данных. Когда последняя операция с БД падает, транзакция откатывается, отменяя первую операцию с БД, но REST-вызов остаётся выполненным. Это может привести к несогласованности данных.

Длинный ответ

Транзакции в Spring управляют только ресурсами, поддерживающими транзакционность (например, БД), но не внешними вызовами.

Поведение в описанном сценарии:

  1. Границы транзакции:

    • Транзакция начинается перед первой операцией с БД

    • Охватывает только операции с транзакционными ресурсами

    • Внешние вызовы (REST, messaging) находятся вне контроля транзакции

  2. Последовательность событий:

    @Transactional
    public void process() {
        // 1. Операция с БД - выполняется в транзакции
        userRepository.save(user);
        
        // 2. REST-вызов - выполняется ВНЕ транзакции
        restTemplate.postForObject("http://api.com/notify", data, String.class);
        
        // 3. Ещё одна операция с БД - в транзакции
        orderRepository.save(order); // ← если здесь исключение
    }
  3. Что происходит при ошибке:

    • REST-вызов уже завершён и не может быть отменён

    • Транзакция откатывается, отменяя первую операцию save()

    • Возникает несогласованность: уведомление отправлено, но данные не сохранены

Решение проблемы:

  1. Перепроектирование логики:

    • Вынести REST-вызов за пределы транзакции

    • Использовать паттерн "Transaction-outbox"

    • Применить компенсирующие транзакции

  2. Использование Saga-паттерна:

    • Разбить процесс на этапы

    • Для каждого этапа предусмотреть компенсирующее действие

  3. Асинхронная обработка:

    • Сохранить задачу на отправку в БД в той же транзакции

    • Отправлять REST-запросы асинхронно после коммита транзакции

Вывод: Внешние вызовы не участвуют в транзакциях, что требует особого подхода к проектированию распределённых операций.

Уровень

  • Рейтинг:

    2

  • Сложность:

    7

Навыки

  • Spring

    Spring

Ключевые слова

#transaction

#spring

Подпишись на Java Developer в телеграм