Sobes.tech
Назад к вопросам
Senior
5

Вопрос 8. Есть сервис ExampleService (см. рис). Метод OrderDao::delete удаляет заказ из БД сервиса. Метод DeliveryService::cancelDelivery синхронно обращается к другому сервису по http и в случае ошибки выбрасывает RuntimeException. Возможно ли использование аннотации @Transactional над методом ExampleService::handle для обеспечения консистентности? @Component @RequiredArgsConstructor public class ExampleService { private final OrderDao orderDao; private final DeliveryService deliveryService; @Transactional public void handle(long orderId) { orderDao.delete(orderId); deliveryService.cancelDelivery(orderId); } } - Да, в случае ошибки изменения в БД откатятся - Нет, пользователь не узнает, что заказ не был удален - Нет, могут возникнуть утечки памяти в слое http клиента - Нет, могут возникнуть таймауты в слое обращения к БД

Компании, где спрашивали
RT Labs

Ответ от нейросети

sobes.tech AI

Аннотация @Transactional в Spring управляет транзакциями на уровне базы данных, обеспечивая атомарность операций с БД внутри одного сервиса.

В данном случае метод ExampleService::handle вызывает orderDao.delete — операцию с БД, и deliveryService.cancelDelivery — HTTP вызов к другому сервису.

Проблема в том, что транзакция @Transactional не распространяется на внешние HTTP вызовы. Если deliveryService.cancelDelivery выбросит RuntimeException, то транзакция с удалением заказа в БД откатится, и заказ не удалится.

Однако, если deliveryService.cancelDelivery завершится с ошибкой после удаления заказа, то транзакция откатится, и пользователь узнает, что заказ не был удален.

Таким образом, ответ:

  • Да, в случае ошибки изменения в БД откатятся

Но важно понимать, что @Transactional не обеспечивает распределённую транзакционность между сервисами. Для консистентности между сервисами нужны другие паттерны (например, саги, компенсационные транзакции).

Другие варианты ответов не соответствуют сути:

  • Пользователь узнает об ошибке, так как RuntimeException выбрасывается
  • Утечки памяти и таймауты не связаны напрямую с @Transactional

Итог: использование @Transactional здесь возможно и откатит изменения в БД при ошибке, но не гарантирует консистентность между сервисами.