Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Войти

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

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

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Spring: Spring, Transaction, Propagation, REQUIRED, REQUIRES_NEW

В чем разница между REQUIRED и REQUIRES_NEW?

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

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

REQUIRED и REQUIRES_NEW — это уровни распространения транзакций в Spring. REQUIRED — это поведение по умолчанию: если транзакция уже существует, метод присоединится к ней, если нет — создаст новую. REQUIRES_NEW всегда создает новую, независимую транзакцию, приостанавливая существующую, если она есть. Ключевая разница в том, что при REQUIRES_NEW откат внутренней транзакции не затрагивает внешнюю, а при REQUIRED — откат в любом месте откатывает всю единую транзакцию.

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

В Spring Framework управление транзакциями — ключевая часть для обеспечения целостности данных. Механизм распространения транзакций определяет, как должна вести себя транзакция при вызове одного методом, помеченным @Transactional, другого такого же метода. Два наиболее часто используемых и сравниваемых уровня — REQUIRED и REQUIRES_NEW.

REQUIRED (Обязательная)

Это уровень распространения по умолчанию. Его логика проста:

  • Если в момент вызова метода уже существует активная транзакция, метод выполняется в её контексте.
  • Если активной транзакции нет, Spring создаёт новую.

Таким образом, несколько методов могут участвовать в одной общей транзакции. Это полезно для объединения операций в атомарную единицу работы. Однако есть и обратная сторона: если в любом из этих методов произойдёт ошибка и будет выброшено исключение, откатится вся транзакция, включая изменения, сделанные ранее вызванными методами.

REQUIRES_NEW (Требует новую)

Этот уровень обеспечивает полную независимость транзакций:

  • При вызове метода Spring всегда приостанавливает существующую транзакцию (если она есть) и создаёт совершенно новую.
  • Новая транзакция завершается (коммитится или откатывается) независимо от внешней транзакции.
  • После завершения внутренней транзакции внешняя транзакция возобновляется.

Это создаёт границу между операциями. Откат внутренней транзакции не повлияет на внешнюю, и наоборот (хотя исключение из внутреннего метода может быть проброшено и прервать внешнюю транзакцию).

Практический пример и применение

REQUIRES_NEW часто используется для операций логирования или аудита, которые должны быть сохранены в базе данных даже в случае отката основной бизнес-транзакции. Рассмотрим пример сервиса:

@Service
public class OrderService {
    @Autowired
    private AuditService auditService;
    @Autowired
    private OrderRepository orderRepository;

    @Transactional(propagation = Propagation.REQUIRED)
    public void placeOrder(Order order) {
        // Основная бизнес-логика
        orderRepository.save(order);
        // Вызов метода с независимой транзакцией для логирования
        auditService.logEvent("Order placed", order.getId());
        // Если здесь выбросится исключение, orderRepository.save откатится,
        // но запись в логе от auditService сохранится.
    }
}

@Service
public class AuditService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logEvent(String message, Long entityId) {
        // Эта операция выполняется в своей, отдельной транзакции.
        AuditLog log = new AuditLog(message, entityId);
        // save выполняется и коммитится независимо.
    }
}

В этом сценарии запись в лог аудита будет сохранена в базе данных, даже если основная транзакция placeOrder будет откачена из-за исключения после вызова logEvent.

Вывод: Используйте REQUIRED для объединения операций в единую атомарную транзакцию (например, создание заказа и списание товаров со склада). Применяйте REQUIRES_NEW, когда нужно гарантировать сохранение определённых операций (логирование, отправка уведомлений) независимо от успеха или неудачи основной бизнес-транзакции, или для изоляции критических операций друг от друга.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Spring

    Spring

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

#Spring

#Transaction

#Propagation

#REQUIRED

#REQUIRES_NEW

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