В книге "Hibernate in action" в описании архитектуры веб-приложения описывается способ создания/закрытия сессии через фильтр. То есть на каждый запрос(http-запрос) к приложению в начале сессия открывается, в конце обработки запроса (http-запроса) сессия закрывается.
Но, если в приложении используется работа с detached объектами (сохраняющимися в http-сессии между запросами), то могут возникнуть проблемы с ними (здесь
Поэтому есть вопрос — зачем нужно закрывать hibernate-сессию после отработки каждого http-запроса? Про освобождение ресурсов понятно.
Но, если на приложение не предполагается большой конкуррентной нагрузки, то приемлим ли способ открытия hibernate-сессии при старте приложения и ее закрытия при смерти http-сессии (через session listener)?
Здравствуйте, manenkov, Вы писали:
M>Поэтому есть вопрос — зачем нужно закрывать hibernate-сессию после отработки каждого http-запроса? Про освобождение ресурсов понятно. M>Но, если на приложение не предполагается большой конкуррентной нагрузки, то приемлим ли способ открытия hibernate-сессии при старте приложения и ее закрытия при смерти http-сессии (через session listener)?
Насколько я помню, hibernate-сессия == транзакция. Если это верно всегда, то твой способ неприемлим. Транзакции должны быть максимально короткими.
Здравствуйте, manenkov, Вы писали:
M>Но, если на приложение не предполагается большой конкуррентной нагрузки, то приемлим ли способ открытия hibernate-сессии при старте приложения и ее закрытия при смерти http-сессии (через session listener)?
Такой вариант организации тоже существует. Про него даже можно найти информацию в reference: http://www.hibernate.org/hib_docs/reference/en/html/transactions.html
Только один важный момент. Не должно быть конкурентного доступа в рамках одной сессии. Например кнопку два раза нажал. Или AJAX запрос параллельно едет.
Здравствуйте, Дм.Григорьев, Вы писали:
M>>Поэтому есть вопрос — зачем нужно закрывать hibernate-сессию после отработки каждого http-запроса? Про освобождение ресурсов понятно. M>>Но, если на приложение не предполагается большой конкуррентной нагрузки, то приемлим ли способ открытия hibernate-сессии при старте приложения и ее закрытия при смерти http-сессии (через session listener)?
ДГ>Насколько я помню, hibernate-сессия == транзакция.
Не-а. Как я понимаю, то даже != сессия БД (по крайней мере так можно настроить).
Проблема в том, http сессия соотносится к http request как 1 ко многим. Сессии Hibernate не потокобезопасные, а значит, если открыть одну хибернайтовую сессию на http сессию, то нельзя будет паралельно обрабатывать два реквеста связанных с одной http сессией.
Плюс остаётся необходимость закрывать сессию при возникновении ошибок в БД (constraint violation, например) и еще в добавок появляется необходимость руками экспайрить объекты, которые закешировались в сессии. И всё ради чего?
ДГ>Насколько я помню, hibernate-сессия == транзакция. Если это верно всегда, то твой способ неприемлим. Транзакции должны быть максимально короткими.
не.. тогда даже смысла б не было в разделении понятий. В рамках одной хиб сессии возможно несколько транзакций (Begin a unit of work and return the associated Transaction object. If a new underlying transaction is required, begin the transaction. Otherwise continue the new work in the context of the existing underlying transaction. The class of the returned Transaction object is determined by the property hibernate.transaction_factory.)
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Плюс остаётся необходимость закрывать сессию при возникновении ошибок в БД (constraint violation, например)
А с чем связано то требование? (закрытие сессии при возникновении ошибки в БД?) Откат транзакции это понятно, но зачем закрывать сессию?
Здравствуйте, manenkov, Вы писали:
ANS>>Плюс остаётся необходимость закрывать сессию при возникновении ошибок в БД (constraint violation, например) M>А с чем связано то требование? (закрытие сессии при возникновении ошибки в БД?) Откат транзакции это понятно, но зачем закрывать сессию?
как минимум — инвалидация кеша. возможно еще что-то есть.
Здравствуйте, manenkov, Вы писали:
M>Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>>Плюс остаётся необходимость закрывать сессию при возникновении ошибок в БД (constraint violation, например) M>А с чем связано то требование? (закрытие сессии при возникновении ошибки в БД?) Откат транзакции это понятно, но зачем закрывать сессию?
11.2.3. Exception handling
If the Session throws an exception (including any SQLException), you should immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block.
Здравствуйте, pvnic, Вы писали:
P>не.. тогда даже смысла б не было в разделении понятий. В рамках одной хиб сессии возможно несколько транзакций [skipped]
Точно, посыпаю голову пеплом. Забыл про conversations.
ANS>>Плюс остаётся необходимость закрывать сессию при возникновении ошибок в БД (constraint violation, например) M>А с чем связано то требование? (закрытие сессии при возникновении ошибки в БД?) Откат транзакции это понятно, но зачем закрывать сессию?
В документации на Hibernate написано, что сессию нельзя использовать в дальнейшем при вылете любой SQL ошибки. Связано это, как я понимаю, с тем, что теряется инфа о том, какие поля в каких объектах обновились. Лично я использую одну сессию на один запрос.