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