Подтвердить что ты не робот

Несколько транзакций в одном сеансе спящего режима (с помощью Spring)

Можно ли моделировать следующее, используя Hibernate + Spring.

  • Открыть сеанс
  • Начать транзакцию
  • Сделайте некоторые работы.
  • Фиксировать
  • Начать транзакцию
  • Дополнительная работа
  • Фиксировать
  • Закрытие сеанса

Я использую Spring TransactionTemplate, который выполняет как просмотр сеанса + транзакции.

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

Возможно ли это?

4b9b3361

Ответ 1

Да, сеансы Hibernate могут начинаться и совершать несколько транзакций. Что вам нужно сделать, так это хранить открытую сессию, а затем повторно использовать ее. Обратите внимание: этот сеанс не является потокобезопасным объектом, но если вы уверены, что он не будет иметь проблем с concurrency, вам нужно просто использовать TransactionSynchronizationUtils, чтобы связать сеанс с ресурсами потока, а затем отключить по желанию вы можете найти пример здесь, или вы можете взглянуть на OSIV и его стандартные реализации.

Это очень сложная вещь, гораздо проще и желательно, чтобы вы сразу закрыли сессию и не использовали ее повторно, потому что это может вызвать проблемы:

  • Объекты внутри кеша автоматически не вытесняются, поэтому ваш сеанс будет увеличиваться в размере до OutOfMemory.
  • Объекты внутри сеанса не очищаются, если они не загрязнены, поэтому вероятность того, что объект был изменен другим пользователем, больше и больше. Убедитесь, что только один пользователь будет изменять записываемые объекты.
  • Если какое-то исключение происходит на одном из шагов, вы должны убедиться, что вы закрываете сеанс. После исключения, произошедшего внутри сеанса, этот объект не может быть повторно использован.
  • Если транзакция была откатна, сеанс очищается Spring, поэтому все ваши объекты становятся отсоединенными. Убедитесь, что вы отбросили все, если хотя бы одна из транзакций была откатна.

Ответ 2

Вы можете достичь этого, используя шаблон OpenSessionInView. Spring предоставляет реализацию javax.servlet.Filter, которую вы можете использовать, если работаете в среде сервлета (вопрос не говорит об этом). Это гарантирует, что сеанс Hibernate будет оставаться открытым на время запроса, а не только для отдельной транзакции.

Javadoc в этом классе довольно обширна и может быть хорошей отправной точкой.