Сессия Java Hibernate и ее объем? - PullRequest
1 голос
/ 14 декабря 2011

Я только начал использовать Hibernate с HSQLDB.В уроке они говорят мне не использовать анти-паттерн "сеанс на операцию".Однако каждый раз, когда я фиксирую транзакцию, сессия также закрывается.Как я должен избегать использования getCurrentSession(), если commit() закрывает сессию?

Мне немного любопытно, как люди обычно меняют сессию.Я видел несколько примеров создания веб-приложений, где у вас есть один сеанс на запрос.В моем случае я создаю сервис и не могу применить ту же идею.Служба работает круглосуточно и время от времени выполняет некоторые операции с базой данных.Должен ли я поддерживать сеанс базы данных все время живым и просто использовать транзакции в качестве границ между операциями (учитывая случай, когда мои транзакции фиксируют транзакцию, не закрывают сеанс), или я должен просто создать новый для каждой операции (что являетсяшаблон, а как иначе?).

Заранее спасибо!

1 Ответ

3 голосов
/ 14 декабря 2011

Это поведение определяется реализацией CurrentSessionContext в использовании. По умолчанию используется значение ThreadLocalSessionContext , которое выполняет закрытие при фиксации, но вы никоим образом не ограничены этим.

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


Ответ на комментарий становился слишком большим для комментария.

Это поведение по умолчанию, потому что это единственное, что является «безопасным» без дополнительной работы или настройки, предоставленной пользователем. «Коммит» - это единственная точка жизненного цикла, которую Hibernate может «увидеть», если вы не поможете ей, поэтому он должен закрыть ее или рискнуть, что сессия останется навсегда.

Определение потенциальных границ жизненного цикла сеанса требует достаточных знаний о том, что вы на самом деле делаете. «Это фоновый сервис» - это не так уж и много. Предполагая, что это что-то вроде бездействия и просыпания каждые X минут, сделайте некоторую работу, затем вернитесь ко сну еще на X минут, тогда это было бы хорошей границей для открытия и закрытия сессии.

Возможно, вы используете слишком широкое определение «операция», когда говорите, что «сеанс на операцию» является антишаблоном.

Они означают, что не делайте что-то вроде (фиктивные требования к вашим услугам):

  1. Услуга пробуждения
  2. Открытая сессия
  3. Чтение местоположения файла из базы данных
  4. Закрытие сессии
  5. Открыть файл
  6. Открытая сессия
  7. Обновить таблицы базы данных из текущего состояния файла
  8. Закрытие сессии
  9. Открытая сессия
  10. Запись журнала активности в базу данных
  11. Закрытие сессии
  12. Служба сна

Было бы совершенно разумно сделать это за один сеанс, а затем закрыть его в конце. В однопоточной среде, где вы сами управляете всем в пределах известных границ, вы можете просто открыть и закрыть сеанс самостоятельно, не используя currentSession, если хотите. Вам просто нужно убедиться, что он будет закрыт в случае исключения. Если вы прослушиваете событие операционной системы, обработка события будет идеальной областью для сеанса.

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