Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Войти

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

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

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Spring: Spring, Transactional, propagation, REQUIRES_NEW, transaction management

Что означает propagation = REQUIRES_NEW?

Вопрос проверяет понимание поведения транзакций в Spring при использовании аннотации @Transactional с propagation = REQUIRES_NEW, что необходимо для изоляции критических операций.

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

Propagation = REQUIRES_NEW указывает, что метод должен выполняться в новой, независимой транзакции. Если существует текущая транзакция, она приостанавливается на время выполнения этого метода. Новая транзакция полностью изолирована: её коммит или откат не влияют на внешнюю транзакцию. Это полезно для операций логирования или аудита, которые должны сохраниться, даже если основная бизнес-транзакция будет откачена.

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

В Spring Framework аннотация @Transactional позволяет управлять границами транзакций декларативно. Одним из ключевых атрибутов этой аннотации является propagation, который определяет, как должна вести себя транзакция, если она уже существует в текущем контексте выполнения.

Что такое REQUIRES_NEW?

Поведение Propagation.REQUIRES_NEW означает, что метод всегда запускается в новой, независимой физической транзакции. Если на момент вызова метода уже существует активная транзакция (например, в вызывающем методе), она временно приостанавливается. Spring создаёт новую транзакцию, выполняет метод внутри неё, а после завершения (коммита или отката) возобновляет предыдущую, приостановленную транзакцию.

Ключевые аспекты и применение

  • Полная изоляция: Новая транзакция имеет собственное соединение с базой данных и уровень изоляции. Её результат (успешный коммит) сохраняется в БД немедленно, независимо от исхода внешней транзакции.
  • Типичные сценарии использования: Это поведение критически важно для операций, которые должны быть записаны в любом случае. Например, запись логов аудита в отдельную таблицу или отправка уведомления о начале процесса. Даже если основная бизнес-транзакция будет откачена (rollback), запись в логе останется.
  • Важное предупреждение: Создание новой транзакции — более ресурсоёмкая операция. Также нужно быть осторожным с deadlock-ами, так как метод может заблокировать данные, ожидаемые внешней транзакцией.

Пример кода

@Service
public class OrderService {
    @Transactional
    public void placeOrder(Order order) {
        // Основная бизнес-логика, работающая в транзакции "A"
        orderRepository.save(order);
        // Вызов метода с REQUIRES_NEW
        auditService.logEvent("Order placed", order.getId());
        // Если здесь выбросится исключение, транзакция "A" откатится,
        // но запись в логе, сделанная auditService, уже сохранена.
    }
}

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

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

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Spring

    Spring

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

#Spring

#Transactional

#propagation

#REQUIRES_NEW

#transaction management

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