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