Как запустить несколько Hibernate SessionFactories с помощью схемы SAME db с использованием распределенного Ehcache - PullRequest
1 голос
/ 16 марта 2011

У нас есть система с n числом клиентов (55 на данный момент), где каждый клиент получает свою собственную базу данных, каждая из которых имеет одинаковую схему. Мы используем hibernate 3.6.1, поддерживаемый распределенным ehcache. Это было реализовано с помощью SessionFactory для каждой базы данных через SessionFactoryService, который во время выполнения «лениво» создает один SessionFactory для каждого клиента на jvm (хранится в HashMap), поэтому мы запускаем управляемый приложением набор SessionFactories. Существует один базовый файл конфигурации Hibernate, остальные настройки выполняются программно во время создания. Наши репозитории (или DAO, как их чаще называют) получают доступ к SessionFactory через SessionFactoryService. Мы в полной мере используем преимущества спящего кеша второго уровня, поддерживаемого SingltonEhcacheRegionFactory, который распространяется. Поскольку мы выполняем n SessionFactories на jvm, нам не нужен NON SingltonEhacheRegionFactory (т. Е. Имеющий CacheManager на SessionFactory), поскольку между SessionFactories будет слишком много межсайтового взаимодействия при попытке поддерживать синхронизацию между кэшами. Поэтому нам нужно только общение между серверами, а не общение внутри сервера, и это было достигнуто с помощью SingltonEhcacheRegionFactory.

Теперь здесь начинается самое интересное. При описанной выше настройке будут возникать коллизии в кэше, поскольку невозможно гарантировать уникальные ключи в качестве схем базы данных, и, следовательно, объекты-сущности, поддерживающие их, одинаковы во всех SessionFactories. Чтобы сделать их уникальными, мы установили для поля hibernate.cache.region_pre-fix уникальное значение для SessionFactory с помощью шага программной настройки, описанного выше. Это удовлетворяет взгляду Hibernate на кэш второго уровня, НО в базовом одноэлементном ehcache теперь есть проблема. Он не может найти правильную конфигурацию, так как конфигурации, указанные в файле конфигурации ehache.xml, не имеют префикса кеша в имени кеша (и при этом они не могли быть, так как для каждой конфигурации кеша должна быть дублирующая запись для каждого префикса, который есть п номер). Это вызывает следующую ошибку:

10: 37: 38,389 ПРЕДУПРЕЖДЕНИЕ AbstractEhcacheRegionFactory: 201 - В конфигурации Hibernate не найдено TransactionManagerLookup, кэши XA будут участвовать в двухфазной фиксации! 10: 37: 39,675 WARN AbstractEhcacheRegionFactory: 143 - Не удалось найти конкретную конфигурацию ehcache для кэша с именем [some_prefix.adc]; используя значения по умолчанию. 10: 37: 40,328 WARN AbstractEhcacheRegionFactory: 143 - Не удалось найти конкретную конфигурацию ehcache для кэша с именем [some_prefix.org.hibernate.cache.UpdateTimestampsCache]; используя значения по умолчанию. 10: 37: 40,331 WARN AbstractEhcacheRegionFactory: 143 - Не удалось найти конкретную конфигурацию ehcache для кэша с именем [some_prefix.org.hibernate.cache.StandardQueryCache]; с использованием значений по умолчанию.

Таким образом, вопрос в том, как мы можем создать несколько SessionFactory с распределенной синглтон-библиотекой ehcache для jvm? Есть ли способ настроить ehcache, чтобы быть осведомленным о предварительном исправлении региона? Решение, которое мы реализовали, в лучшем случае хакерское. Мы реализовали наш собственный hibernate.cache.region.factory_class, который расширяет SingltonEhcacheRegionFactory (и удалили конфигурацию префикса области кэша hibernate). Все, что делает наша реализация, это перехватывает вызовы методов к базовому Ehcache и добавляет предварительное исправление ко всем ключам, используемым для операций кэширования, тем самым предотвращая конфликты кэша. Мы хотели бы получить более «готовое» решение, и по понятным причинам то, что мы реализовали, хотя оно работает, не является идеальным. Я прочитал все, что я могу найти по этому вопросу, и не нашел решения, которое бы работало с несколькими SessionFactories с ЖЕ СХЕМОЙ (и, что наиболее важно) с использованием распределенного кэша второго уровня. Любые идеи, решения или советы будут высоко ценится. Я даже открыт для совершенно другого дизайна, если у кого-то есть хороший способ удовлетворить требования. Заранее спасибо!

1 Ответ

0 голосов
/ 17 марта 2011

При описанной выше настройке будут происходить коллизии кеша, поскольку невозможно гарантировать уникальные ключи в качестве схем базы данных, и, следовательно, объекты сущности, поддерживающие их, одинаковы в SessionFactories

Что ты имеешь в виду? Если вы используете одну и ту же схему для всех клиентов, безусловно, есть способ гарантировать уникальные ключи. Для этого есть множество методов, в том числе использование UUID или алгоритма Hilo Hibernate.

Чтобы сделать их уникальными, мы установили для поля hibernate.cache.region_pre-fix уникальное значение для SessionFactory с помощью шага программной настройки выше

Не уверен, что понял. Ты имеешь в виду, что для получения уникальных ключей нужны разные регионы кеша? Если это так, то это не так :-) Области кэша должны быть «пространством имен» для сущностей (Car, Person, Account), а не для записей (Car # 1, Car # 2).

как мы можем создать несколько SessionFactory с распределенной синглтон-библиотекой для каждой среды jvm?

Несколько сеансовых фабрик не являются проблемой. Не уверен насчет ehcache, но я хотел бы рассмотреть возможность использования «сервера кэширования», такого как Infinispan. Вы можете запустить его в своей собственной JVM, и все клиенты будут обращаться к нему всякий раз, когда захотят получить доступ к кешу. Опять же, не уверен, что я правильно понял вашу среду, но при использовании кеша вы должны использовать настройку, которая гарантирует, что данные, которые видит клиент № 1, совпадают с данными клиента № 2.

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

Подробнее о Infinispan с Hibernate можно прочитать здесь: http://community.jboss.org/wiki/usinginfinispanasjpahibernatesecondlevelcacheprovider

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