Как закрыть сессию (и вернуть соединение БД в пул) рано при использовании OpenSessionInViewInterceptor - PullRequest
1 голос
/ 18 октября 2011

Веб-приложение использует Spring * OpenSessionInViewInterceptor для открытия сеанса Hibernate для каждого запроса, закрывая его в конце обработки запроса. Это работает очень хорошо. Однако некоторые запросы, такие как загрузка файлов, могут длиться долго, оставляя сеанс открытым и связывая соединение с БД. В нашем случае копирование данных файла в поток вывода ответа - это последнее, что делает контроллер, и не требует сеанса Hibernate (данные файла считываются из файловой системы сервера). Эти запросы на загрузку файлов могут быстро занять большинство соединений в нашем пуле соединений с БД.

Я дал контроллеру ссылку на SessionFactory и вызвал следующий метод непосредственно перед копированием данных файла в поток вывода ответа:

SessionFactoryUtils.closeSession(SessionFactoryUtils.getSession(sessionFactory, false));

OpenSessionInViewInterceptor делает то же самое позже в процессе запроса, и закрытие сеанса кажется идемпотентным (то есть, вызов этого метода несколько раз имеет тот же эффект, что и вызов его один раз). Другими словами, локальное тестирование этого изменения прошло хорошо. Но это кажется немного опасным; если OpenSessionInViewInterceptor или SessionFactoryUtils изменится в более поздних версиях Spring, этот подход может быть неявным (возможно, утечка соединений?).

Конечная цель - закрыть соединение с базой данных перед началом отправки данных файла, и это один из способов достижения этого. Другим решением будет контроллер, помещающий входной поток в запрос как атрибут, и имеющий фильтр (стреляющий после OpenSessionInViewInterceptor), который копирует данные входного потока в ответ. У этого есть свой собственный набор проблем (например, соответствующий код теперь разделен между контроллером и фильтром, а не централизован в контроллере).

Есть ли лучший способ справиться с этим?

1 Ответ

2 голосов
/ 18 октября 2011

Один из вариантов - не использовать OSiV для контроллеров / действий, возвращающих файл.Другой вариант - создать свою собственную версию, в которой вы были бы более уверены (в конце концов, она не очень сложная).

Я сомневаюсь, что вы бы утекли соединений, если изменился перехватчик / утилиты,Я не взволнован идеей иметь что-то, что возвращало файл после того, как перехватчик сделал свое дело;это подразумевает наличие некоторого зависшего состояния, отслеживаемого последующим перехватчиком (или фильтром, хотя IMO, выполняющий это в цепочечном перехватчике, вероятно, чище), и это кажется мне неуклюжим и подверженным ошибкам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...