TGViewer
Java Portal | Программирование Java Portal | Программирование @java_iibrary · 11.6K subscribers
Post #1846 2.16K
Сценарный вопрос с реального интервью по Java/Spring Boot:

В контроллере вызывается метод сервиса, помеченный аннотацией @Transactional.
Этот метод не только сохраняет сущность, но и отправляет два письма: одно администратору, другое — пользователю, который сделал запрос.

Класс, отвечающий за отправку почты, помечен аннотацией @Async, но Spring всё равно выполняет его синхронно.
В итоге API обрабатывает запрос целых 12 секунд — очевидно, это неприемлемо.

Вопрос: почему так происходит и как это исправить?

Реальная причина:

Когда используется @Transactional, Spring создаёт прокси для транзакции.
Если внутри этого же контекста вызывается @Async-метод, то Spring не создаёт новый поток — потому что вызов происходит внутри того же прокси.

Иными словами, асинхронный код оказывается «заперт» внутри транзакции.

В результате, коммит в базу ждёт, пока оба письма не будут отправлены.

Как исправить:

Заменить прямой вызов отправки писем на event-publisher подход.

После сохранения запроса просто опубликовать событие, например DemoRequestCreatedEvent.

Асинхронные слушатели (@EventListener + @Async) будут обрабатывать отправку писем вне основной транзакции.

Что получаем:

Транзакция завершается за ~100 мс вместо 12 секунд.

API реагирует почти мгновенно.

Письма всё так же надёжно уходят в фоне.

Использование событий и асинхронных слушателей — не просто красивая архитектурная штука, а реальный способ сделать систему быстрой, масштабируемой и профессиональной.

Дополнительный вопрос:
Кроме событий, какие подходы ты используешь, чтобы отделить транзакционную логику (например, коммит в БД) от побочных эффектов вроде отправки писем или уведомлений?

@Java_Iibrary
  • 👍 9
  • ❤ 2
More from @java_iibrary
  1. Sep 28, 2026💡 Java: не создавайте ресурсоёмкие объекты, пока они действительно не понадобятся. ✅ Иниц…
  2. Sep 28, 2026Проблема в продакшене. Приложение зависло. Вы запускаете: jstack <pid> Через несколько сек…
  3. Sep 27, 2026Java-разработчики, CopyOnWriteArrayList создаёт копию всего внутреннего массива при каждом…
  4. Sep 27, 2026Java-разработчики, ConcurrentHashMap потокобезопасен. Но он не блокирует всю коллекцию при…
  5. Sep 26, 2026Во многих приложениях есть такой эндпоинт. Фронтенд удаляет JWT после того, как пользовате…
  6. Sep 26, 2026Java: используйте Deque вместо Stack для работы по принципу LIFO («последним пришёл — перв…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →