Лучший способ обработки сеансов Hibernate в многоуровневом веб-приложении Spring MVC - PullRequest
12 голосов
/ 17 июля 2011

Если у нас есть веб-приложение с

  • тяжелым пользовательским интерфейсом (Spring MVC + JQuery с JSON)
  • Hibernate с аннотациями JPA, являющимися моделью домена
  • расширить предоставляемый Spring DAO для уровня кода DAO
  • JBOSS, являющийся сервером приложений с Oracle в качестве внутреннего сервера
  • Пул соединений на основе источника данных (JNDI) (не XA, а локальный источник данных)
  • также имеет доступ к нескольким источникам данных (для работы с несколькими БД)

Поведенчески, много данных (70%) и обновление данных составляет 30%
Что было бы лучшимдля того, чтобы эффективно потреблять соединения с БД, а также следить за тем, чтобы не было большой утечки при использовании соединения?

  1. Было бы лучше выбрать DAO на основе шаблонов Hibernate?
  2. Какой тип менеджера транзакций может быть предложен, и нам следует обратиться к управлению транзакциями на основе AOP. *
  3. , где создать экземпляр сеанса и где закрыть сеансы, чтобы эффективно использовать соединения из пула соединений.,
  4. Это правда, что нам нужно обрабатывать транзакции из уровня Service, но что произойдет с сеансами, если они будут ждать дольше (мы не используем opensessioninviewFilter)
  5. , какой уровень лучше обрабатыватьпроверенные исключения (бизнес-исключения) и исключения во время выполнения.

Извините за этот немного более длинный вопрос, однако я вижу, что это общий запрос, и я попытался объединить его.Цените ваше терпение и руководство.Спасибо за вашу помощь.

Ответы [ 2 ]

16 голосов
/ 17 июля 2011

Это звучит как довольно типичное приложение Spring / Hibernate, поэтому я бы рекомендовал следовать текущим рекомендациям, которые я недавно обрисовал в другой ответ . В частности:

  1. Не не расширять классы поддержки Spring DAO или использовать HibernateTemplate. Используйте аннотацию @ Repository в сочетании с компонентным сканированием, и непосредственно внедрит SessionFactory в ваш DAO.
  2. Используйте Spring HibernateTransactionManager и определенно используйте декларативное управление транзакциями через @ Transactional в качестве подхода по умолчанию.
  3. Пусть Весна справится с этим . По умолчанию он открывает сеансы как раз вовремя для транзакций, но предпочитает открытый сеанс в шаблоне представления , включенный Spring OpenSessionInViewFilter .
  4. См. № 3.
  5. Всегда обрабатывайте исключения там, где они должны обрабатываться - другими словами, это дизайнерское решение. Однако обратите внимание, что среда транзакций Spring по умолчанию откатывает на непроверенные исключения , но не проверяется, чтобы соответствовать поведению спецификации EJB. Обязательно установите правильные правила отката (см. Предыдущую ссылку) везде, где вы используете отмеченные исключения.

Кроме того, очевидно, используйте пул соединений. Apache Commons DBCP - отличный выбор. «Небольшая утечка в использовании соединения» не достаточно. Вы должны иметь нулевую утечку соединения. В зависимости от Spring управление вашими ресурсами поможет в этом. Что касается других проблем с производительностью, не пытайтесь оптимизировать преждевременно. Подождите, пока вы не увидите, где находятся ваши проблемные области, а затем найдите лучший способ решить каждую из них в отдельности. Поскольку ваши узкие места, скорее всего, будут связаны с базой данных, ознакомьтесь с главой о производительности справки Hibernate, чтобы понять, с чем вы столкнулись. Он охватывает важные концепции стратегий кэширования и выборки.

2 голосов
/ 17 июля 2011
  • Используйте JPA EntityManager непосредственно в ваших DAO.Не забудьте пометить его как расширенный
  • Предпочтительный <tx:annotation-driven /> и @Transactional - только на уровне обслуживания
  • Диспетчер транзакций также открывает и закрывает сеансы (если они еще не существуют)в теме).Здесь полезно знать, что сессии являются сеансами по запросу.Каждый запрос (= поток) имеет отдельный экземпляр сеанса.Но соединение с базой данных создается, только если оно необходимо, поэтому даже если вокруг всех методов есть диспетчер транзакций, ненужные соединения не будут открываться.
  • транзакции только для чтения - используйте @Transactional(readOnly=true) в тех случаях, когда есть только извлечение данных.
  • кэширование - используйте кэш 2-го уровня гибернации для помещения объектов в память (вместо того, чтобы извлекать их из базы данных каждыйвремя)
  • избегайте OpenSessionInView и ленивых коллекций.Это субъективно, но, по моему мнению, все объекты, которые покидают сервисный уровень, должны быть инициализированы.Для небольших коллекций (например, список ролей) вы можете иметь нетерпеливые коллекции.Для больших коллекций используйте HQL-запросы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...