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

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

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

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

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

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

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

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

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

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

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

1 ответ

Решение

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

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

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

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

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

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

5.1.4.1. Генератор

...

  • uuid

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

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

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

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

2.5. Контекстные сессии

Большинству приложений, использующих Hibernate, нужна некоторая форма "контекстного" сеанса, когда данный сеанс действует во всем контексте данного контекста. Однако в разных приложениях определение того, что составляет контекст, обычно отличается; разные контексты определяют разные рамки понятия течения. В приложениях, использующих Hibernate до версии 3.0, использовались как собственные контекстные сеансы на основе ThreadLocal, так и вспомогательные классы, такие как HibernateUtil, или сторонние платформы, такие как Spring или Pico, которые предоставляли контекстные сеансы на основе прокси / перехвата.

(...)

Однако, начиная с версии 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: текущие сеансы отслеживаются потоком выполнения. Однако вы обязаны связать и отменить привязку экземпляра Session со статическими методами для этого класса: он не открывает, не очищает и не закрывает Session.

(...)

Нет необходимости реализовывать свои собственные 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. Спящий в 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, будут автоматически участвовать в управляемых контейнером транзакциях сервера приложений.

Другие вопросы по тегам