Ответ
Уровни распространения (propagation) в Spring определяют поведение транзакции при вложенных вызовах методов, помеченных @Transactional.
7 уровней propagation в Spring:
| Уровень | Описание | Когда использовать |
|---|---|---|
| REQUIRED (по умолчанию) | Использует существующую транзакцию или создаёт новую | Большинство случаев, стандартное поведение |
| REQUIRES_NEW | Всегда создаёт новую транзакцию, приостанавливая текущую | Независимые операции (логирование, аудит) |
| NESTED | Создаёт вложенную savepoint-транзакцию | Частичный откаток в рамках основной транзакции |
| MANDATORY | Требует активной транзакции, иначе исключение | Методы, которые должны вызываться в транзакционном контексте |
| SUPPORTS | Работает в транзакции, если она есть | Операции чтения, которые могут работать без транзакции |
| NOT_SUPPORTED | Выполняется без транзакции, приостанавливая текущую | Методы, несовместимые с транзакциями (отправка email) |
| NEVER | Требует отсутствия транзакции, иначе исключение | Проверка, что метод не вызывается в транзакции |
Примеры использования:
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
// Использует текущую транзакцию или создаёт новую
orderRepository.save(order);
// Независимая операция логирования
logActivity(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logActivity(Order order) {
// Всегда выполняется в НОВОЙ транзакции
// Откат не повлияет на основную транзакцию createOrder
auditLogRepository.save(new AuditLog("Order created", order.getId()));
}
}
Важные особенности:
- NESTED работает только с некоторыми СУБД (не поддерживается в JPA/Hibernate)
- REQUIRES_NEW требует нового соединения с БД из пула
- При использовании NOT_SUPPORTED/NEVER текущая транзакция приостанавливается
Рекомендации:
- Используйте REQUIRED по умолчанию
- REQUIRES_NEW — для независимых побочных операций
- MANDATORY — для строгого контроля вызова методов
- Избегайте смешивания разных уровней без понимания последствий
Ответ 18+ 🔞
А, слушай, смотри, вот эти ваши propagation levels в Spring, блядь... Это ж как в семье, когда тёща приезжает, понимаешь? Каждый уровень — это разная степень ебалыча и ответственности.
Вот смотри, табличку тебе нарисовали, семь штук, как смертных грехов, блядь. Но главное запомни три, остальные так, для красоты, чтобы архитекторы понтоваться могли.
REQUIRED — это как по умолчанию, стандарт. Ну типа: «Мужики, транзакция есть? Есть? Ну окей, вписываюсь. Нет? Ёбта, ща создам, не ссы». 90% всех методов должны быть с ним, и нехуй мудохаться.
REQUIRES_NEW — это вот отдельная, блядь, песня. Это когда ты такой: «Ой, всё, нахуй, я сам по себе!». Сука, он текущую транзакцию приостанавливает, как будто на паузу ставит, и заводит свою, новую. И если в этой новой пиздец случится — откатится только она, а основная жить будет. Идеально для логирования или отправки каких-нибудь уведомлений в ад, которые не должны всё похерить, если сломаются.
@Transactional(propagation = Propagation.REQUIRES_NEW) // Внимание, блядь! Отдельная касса!
public void logActivity(Order order) {
auditLogRepository.save(new AuditLog("Order created", order.getId()));
// Упади тут — основному заказу похуй, он сохранится.
}
NESTED — это, сука, хитрая жопа. Типа вложенная транзакция через savepoint. Если в дочернем методе пиздец — откатывается не всё, а только до этой точки. Красиво, да? А НО! Блядь, работает не везде, JPA/Hibernate её часто не поддерживает, так что это как ковёр-самолёт — в сказках есть, а на деле хуй.
MANDATORY — это ультиматум. «Я, блядь, буду работать ТОЛЬКО если ты уже в транзакции. Иначе — исключение тебе в ебало, разгильдяй!». Для строгого контроля, чтобы не вызывали метод абы как.
SUPPORTS — пофигист. «Есть транзакция? Ок, работаю в ней. Нету? Ну и похуй, буду без неё». Чисто для чтения данных.
NOT_SUPPORTED — анархист, блядь. «Я ненавижу ваши транзакции!». Он приходит, текущую транзакцию — стоп, на паузу, и работает без неё. Например, чтобы файлы на диск писать или в внешний сервис стучаться.
NEVER — параноик. «Если я вижу активную транзакцию — я вызываю психиатра, то есть исключение!». Чтобы гарантировать, что метод не вызовут внутри транзакционного контекста.
Главный совет, нахуй: Не выёбывайся. Ставь REQUIRED и спи спокойно. REQUIRES_NEW юзай точечно, когда реально нужна изоляция. А про NESTED можешь рассказывать на собеседованиях, чтобы выглядеть умным, но в продакшене её не увидишь, ядрёна вошь. Остальные — так, нишевые прибамбасы для особо извращённых сценариев. Всё, разобрались, иди работай.