Spring-Hibernate используется в веб-приложении, каковы стратегии для потокового безопасного управления сессиями - PullRequest
1 голос
/ 22 июля 2010

Я занимаюсь разработкой веб-приложения для Spring и Hibernate, и я был настолько одержим тем, чтобы сделать его безопасным для работы с потоками и иметь возможность поддерживать большую нагрузку, что на основе моей рекомендации босса я в итоге написал свои собственные session и session container для реализации session per request pattern.Плюс у меня много DAOs и я не желаю писать одно и то же save method для всех DAOs Я копирую и вставляю это Hibernate GenericDAO (я не могу сказать, что это одно и то жепотому что в то время hibernate не принадлежал jboss) и занимался водопроводными работами, и под давлением все быстро усложнялось и находилось в рабочем состоянии, исключение StaleObjectException и правильное дублирование данных, и я чувствую, что пришло время пересмотреть то, что ясделали, упростите его и сделайте его более надежным для обработки больших данных.Одна вещь, которую вы должны знать, это то, что в одном запросе используется много DAO.

Для некоторых обновлений в базе данных запущен кварц.

Столько, сколько я хочу настроить все к лучшему, мне не хватает временипроводить необходимые исследования, плюс Hibernate отчасти огромен (обучается).

Вот и все, я хотел бы позаимствовать ваш опыт и задать несколько вопросов, чтобы узнать, в каком направлении идти.

Вопрос 1 : является ли сгенерированный Hibernate uuid достаточно безопасным для потоковой среды и позволяет избежать StaleObjectException?

Вопрос 2 Какова лучшая стратегия использования hibernate getCurrentSessionв сценарии threadSafe (я читал о потоке локальных вещей, но не слишком разбирался, поэтому не делал этого)

Вопрос 3 : подойдет ли HIbernateTemplate для простейшего подхода к решению?

Вопрос 4 : что вы выберете, если захотите реализовать пул соединений и требования к настройке для рабочего сервера?

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

Спасибо за чтение этого, идея всех приветствуется ...

1 Ответ

14 голосов
/ 23 июля 2010

Я занимаюсь разработкой веб-приложения для Spring и Hibernate, и я был настолько одержим тем, что сделал его потокобезопасным и смог поддерживать большую нагрузку, что на основе моей рекомендации босса я в итоге написал свой собственный сеанс и контейнер сеансов для реализовать сеанс для каждого шаблона запроса.

Вы должны просто отбросить весь этот код и использовать вместо него API-интерфейсы Spring / Hibernate: меньше ошибок, меньше обслуживания.

Я копирую и вставляю этот Hibernate GenericDAO (я не могу сказать, что это одно и то же, потому что в то время hibernate не принадлежал jboss) и делаю сантехнику, и под давлением все быстро усложняется (...)

Вы можете использовать GenericDao и внедрять необходимые вещи с помощью Spring.

Вопрос 1 : достаточно ли безопасен сгенерированный Uiber Uuid для многопоточной среды и позволяет избежать StaleObjectException?

Чтобы строго ответить на ваш вопрос, вот что Справочное руководство пишет о генераторе uuid:

5.1.4.1. Генератор

...

  • uuid

    использует 128-битный алгоритм UUID для генерировать идентификаторы типа string которые являются уникальными в сети ( IP-адрес используется). UUID является кодируется как строка из 32 шестнадцатеричных длина цифры.

Так что я считаю это безопасным. Но я думаю, что ваши StaleObjectException не связаны (это другая проблема).

Вопрос 2 : как лучше всего использовать hibernate getCurrentSession в сценарии threadSafe (я читал о Threadlocal, но не слишком разбираюсь в этом, поэтому не сделал этого)

Лучшая стратегия состоит в том, чтобы просто использовать его, sessionFactory.getCurrentSession() всегда даст вам Session область действия для текущей транзакции базы данных, известную как «контекстный сеанс». Опять цитируем справочную документацию:

2,5. Контекстные сессии

Большинство приложений, использующих Hibernate, необходимо некоторая форма «контекстной» сессии, где данный сеанс действует во всем объеме данного контекст. Тем не менее, через приложения определение того, что составляет контекст обычно отличается; разные контексты определяют разные выходит к понятию тока. Приложения, использующие Hibernate до версия 3.0, как правило, использует либо самодельный ThreadLocal-based контекстные сессии, вспомогательные классы такой как HibernateUtil, или используется сторонние фреймворки, такие как Spring или Пико, который предоставил контекст, основанный на прокси / перехвате сессий.

(...)

Однако, начиная с версии 3.1, обработка позади SessionFactory.getCurrentSession() теперь подключаем. С этой целью новый интерфейс расширения, org.hibernate.context.CurrentSessionContext, и новый параметр конфигурации, hibernate.current_session_context_class, были добавлены, чтобы позволить подключаемость объема и контекста определения текущие сессии.

См. Javadocs для org.hibernate.context.CurrentSessionContext интерфейс для подробного обсуждения его контракт. Определяет один метод, currentSession(), которым реализация отвечает за отслеживание текущего контекста сессия. Готовый, Hibernate поставляется с тремя реализациями этот интерфейс:

  • org.hibernate.context.JTASessionContext: текущие сеансы отслеживаются и ограничен транзакцией JTA. обработка здесь точно такая же, как в старом подходе только JTA. Увидеть Javadocs для деталей.
  • org.hibernate.context.ThreadLocalSessionContext: текущие сессии отслеживаются потоком исполнения. Смотрите Javadocs для подробности.
  • org.hibernate.context.ManagedSessionContext: текущие сессии отслеживаются потоком исполнения. Тем не менее, вы ответственность связывать и отстегивать Экземпляр сеанса со статическими методами на этом классе: он не открывается, очистить или закрыть сеанс.

(...)

В настоящее время нет необходимости внедрять собственное решение на основе ThreadLocal, не делайте этого.

Вопрос 3 : подойдет ли HIbernateTemplate для простейшего подхода к решению?

Ну, HibernateTemplate не рекомендуется, но больше не рекомендуется, и я предпочитаю внедрять DAO без шаблонов :

public class ProductDaoImpl implements ProductDao {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Collection loadProductsByCategory(String category) {
        return this.sessionFactory.getCurrentSession()
                .createQuery("from test.Product product where product.category=?")
                .setParameter(0, category)
                .list();
    }
}

ГдеSessionFactory вводится весной.Я предлагаю прочитать Так что вы все равно должны использовать Spring HibernateTemplate и / или JpaTemplate ?? для полного фона, а также весь раздел 13.3.Hibernate в документации Spring по доступу к данным ORM.

Вопрос 4: что вы выберете, если захотите реализовать пул соединений и требования к настройке для рабочего сервера?

Хм ... Что?Я бы никогда не реализовал свой пул соединений, но использовал бы его с моего сервера приложений.Возможно, вам следует уточнить этот вопрос.

Обновление: В работе я бы не использовал встроенный пул соединений Hibernate, а настроил бы Hibernate на использование источника данных JNDI сервера приложений (и, следовательно,пул соединений с сервером приложений).Из документации:

3.3.Соединения JDBC

...

Вот пример hibernate.properties файла для сервера приложений, предоставленного источником данных JNDI:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

Соединения JDBC, полученные из источника данных JNDI, будут автоматически участвовать в управляемых контейнером транзакциях сервера приложений.

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