Лучший способ обработки сеансов Hibernate в многоуровневом веб-приложении Spring MVC

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

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

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

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

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

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

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

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

  • Используйте JPA EntityManager непосредственно в своих DAO. Обязательно не отмечайте его как Extended
  • Предпочитают и @Transactional – только на уровне обслуживания
  • Менеджер транзакций также открывает и закрывает сеансы (если один из них уже не существует в streamе). Здесь хорошо знать, что сеансы сеанса за запрос. Каждый запрос (= stream) имеет отдельный экземпляр сеанса. Но соединение с базой данных создается только в том случае, если это необходимо, поэтому даже если во всех методах есть менеджер транзакций, ненужные соединения не будут открыты.
  • транзакции только для чтения – используйте @Transactional(readOnly=true) в случаях, когда есть только поиск данных
  • кеширование – использовать спящий 2-й уровень кэша для размещения сущностей в памяти (вместо того, чтобы извлекать их из базы данных каждый раз)
  • избегайте OpenSessionInView и ленивых коллекций. Это субъективно, но, на мой взгляд, все объекты, которые покидают сервисный уровень, должны быть инициализированы. Для небольших коллекций (например, список ролей) у вас могут быть интересные коллекции. Для больших коллекций используются запросы HQL.