В то время как много сообщений было написано на тему Spring OpenSession/EntityManagerInViewFilter, я не мог найти ничего, что упоминает его недостатки. Из того, что я понимаю, и принимая типичную многоуровневую архитектуру веб-приложений, используя сервисный уровень @Transactional, фильтр работает следующим образом:
- Фильтр перехватывает запрос сервлета
- Фильтр открывает EntityManager и связывает его с текущим потоком
- Веб-контроллер называется
- Веб-контроллер вызывает службу
- Перехватчик транзакций начинает новую транзакцию, извлекает связанный с потоком EntityManager и связывает его с транзакцией
- Вызывается служба, выполняет некоторые действия с EntityManager, а затем возвращает
- Перехватчик транзакций сбрасывает EntityManager, затем совершает транзакцию
- Веб-контроллер готовит представление, а затем возвращает
- Вид построен
- Фильтр закрывает EntityManager и отвязывает его от текущего потока
На шагах 8 и 9 все объекты, загруженные потоком EntityManager, все еще управляются. Следовательно, если на этих этапах затрагиваются ленивые ассоциации, они будут загружены из базы данных с использованием еще открытого EntityManager. Насколько я понимаю, каждый такой доступ требует, чтобы база данных открывала транзакцию. Spring управление транзакциями не будет знать об этом, поэтому я называю это "неявной транзакцией".
Я вижу две проблемы с этим:
- Загрузка нескольких ленивых ассоциаций приведет к нескольким транзакциям с базами данных, возможному удару по производительности
- Корневой объект и его ленивые ассоциации загружаются в разные транзакции базы данных, поэтому данные могут быть устаревшими (например, root загружен нитью 1, корневыми ассоциациями, обновленными потоком 2, корневыми ассоциациями, загруженными потоком 1)
С одной стороны, эти 2 проблемы кажутся достаточными, чтобы отклонить использование этого фильтра (поражение производительности, несогласованность данных). С другой стороны, это решение очень удобно, избегает написания нескольких строк кода, проблема 1 может быть не такой заметной, а проблема 2 может быть чистой паранойей.
Как вы думаете?
Спасибо!