Spring-Cloud, Hystrix и JPA — LazyInitializationException

У меня возникла следующая проблема при попытке интегрировать Hystrix в существующее приложение Spring Boot. Я использую загрузку с данными Spring (репозитории jpa). Структура приложения довольно проста: Ресурсы -> Сервисы -> Репозитории.

Я включил поддержку Hystrix и аннотировал один из методов службы, который возвращает объект, следующим образом:

@HystrixCommand(fallback="getDealsFallback")
public Page<Deal> getDeals(...) {
  // Get the deals from the Index Server.
  return indexServerRepository.findDealsBy(...);
}

public Page<Deal> getDealsFallback(...) {
  // If IndexServer is down, query the DB.
  return dealsRepository.findDealsBy(...);
}

Так что это работает, как и ожидалось, настоящая проблема возникает, когда я возвращаю Entity клиенту. Я использую OpenEntityManagerInViewFilter, поэтому я могу сериализовать свою модель с ее отношениями. Когда я использую @HystrixCommand в своем сервисном методе, я получаю исключение LazyInitializatioException при попытке сериализации.

Я знаю причину (или, по крайней мере, я подозреваю, в чем проблема), и это потому, что Hystrix выполняется в другом потоке, поэтому он не является частью транзакции. Изменение стратегии изоляции Hystrix с THREAD на SEMAPHORE работает правильно, поскольку это тот же поток, но я понимаю, что это неправильный подход к проблеме.

Итак, мой вопрос: как я могу сделать исполняемый поток Hystrix частью транзакции. Есть ли обходной путь, который я могу применить?

Спасибо!


person Mauro Monti    schedule 26.03.2015    source источник
comment
под вернуть объект клиенту вы имеете в виду jsp? или в контроллере?   -  person guido    schedule 27.03.2015
comment
Является Rest API, поэтому отвечая на ваш вопрос, JSP.   -  person Mauro Monti    schedule 27.03.2015
comment
Я думаю, что SEMAPHORE - это то, что вам нужно, если вам нужен контекст потока (для этого он и существует).   -  person Dave Syer    schedule 27.03.2015
comment
На странице конфигурации Hystrix (github.com/Netflix/Hystrix/wiki/Configuration) указано Как правило, единственный раз, когда вы должны использовать изоляцию семафора (SEMAPHORE), это когда вызов настолько большой (сотни в секунду, на экземпляр) ... что заставляет меня нервничать, используя эту стратегию только для того, чтобы транзакции работали. Что кто-то еще думает?   -  person Dick Chesterwood    schedule 30.09.2016


Ответы (1)


Это немного старая тема, но, возможно, кто-то тоже сталкивается с этой проблемой. На github есть проблема по этому поводу.

Причина в том, что hystrix будет работать в отдельном потоке, отличном от того, в котором находилась предыдущая транзакция. Так что транзакция и сериализация для ленивых работать не будут.

И «THREAD» также является рекомендуемой стратегией выполнения. Поэтому, если вы хотите использовать и hystrix, и транзакцию, вы должны использовать их в двухуровневых вызовах. Например, в сервисной функции первого уровня используйте транзакцию, а в сервисной функции второго уровня используйте hystrix и вызовите транзакционную функцию первого уровня.

person Mavlarn    schedule 17.05.2017