Получить доступ

Что делает propagation=REQUIRES_NEW и какой подводный камень с пулом соединений он несёт?

Senior@TransactionalSpring
Ещё спрашивают так:
  • Чем REQUIRED отличается от REQUIRES_NEW?
Коротко

REQUIRES_NEW приостанавливает текущую транзакцию и открывает новую независимую — со своим соединением. На это время поток держит два соединения: при большом параллелизме пул исчерпывается, и всё зависает (дедлок на пуле).

  • REQUIRED (по умолчанию) — присоединиться к существующей или создать
  • Типичное применение — аудит или журнал ошибок, который должен сохраниться даже при откате основной
  • Пул из N соединений и N потоков в REQUIRES_NEW — каждый держит одно и ждёт второе

А ещё NESTED — точка сохранения в той же транзакции, без второго соединения

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

REQUIRES_NEW нужен, когда вложенная работа должна зафиксироваться или откатиться независимо от внешней (например, запись в audit/лог, которая должна сохраниться, даже если основная транзакция откатится). Spring приостанавливает (suspend) внешнюю транзакцию и берёт ВТОРОЕ соединение под новую — поэтому в момент выполнения вложенной заняты два соединения от одного потока. На маленьком пуле (например, Hikari на 10) массовые REQUIRES_NEW могут привести к тому, что потоки держат по соединению и ждут второго — connection-pool deadlock. Плюс, как любой @Transactional через self-invocation (вызов внутри того же бина), он не сработает без прокси.

Что хотят услышать

  • Семантика REQUIRES_NEW и отличие от REQUIRED.
  • Почему нужны два соединения и как это кладёт пул.
  • Когда оправдано, альтернатива NESTED.

Частые ошибки

  • Массово использовать REQUIRES_NEW на маленьком пуле соединений.
  • Вызывать REQUIRES_NEW-метод через this (self-invocation) — прокси не перехватит.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Приостанавливает текущую транзакцию и стартует новую независимую (со своим commit/rollback); пока внешняя приостановлена, на время вложенной удерживаются ДВА соединения — при ограниченном пуле это риск deadlock-а на соединениях
  • ✗Присоединяется к существующей транзакции, если она есть
  • ✗Полностью отключает транзакции для метода
  • ✗Делает транзакцию только для чтения

Что спросят дальше

  • Чем REQUIRES_NEW отличается от NESTED?
  • Почему self-invocation ломает @Transactional?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем