Актуальность JPA-кэша с одновременным доступом к базе данных - PullRequest
3 голосов
/ 09 октября 2009

Сервисный уровень, который реализует свою устойчивость на основе JPA, может извлечь огромную выгоду из кэша второго уровня, который прозрачно управляется провайдером JPA (например, Hibernate, Toplink / Toplink Essentials и т. Д.). Когда этот кеш активирован, он содержит экземпляры постоянных классов, как только они были загружены из базы данных в первый раз. Для настройки поведения кэша могут быть специфичные для поставщика расширения.

Стандарт JPA также поддерживает оптимистическую блокировку благодаря наличию отметки времени или поля версии, которое используется для предотвращения повреждения данных при одновременном обновлении. Поскольку этот механизм основан на данных, содержащихся в базе данных, его также можно использовать, когда другие приложения или службы хотят обновить данные - просто включите поле версии записи в обновление, и все готово.

Когда дело доходит до кэширования , поведение выглядит следующим образом: поставщик JPA (по крайней мере, Toplink Essentials) не замечает изменений в базе данных , которые не выполняются с помощью EntityManager.

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

Ответы [ 2 ]

3 голосов
/ 09 октября 2009

Это поведение также верно для Hibernate ( 19.2. Кэш второго уровня ):

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

Это звучит разумно. Как ваш кеш должен знать о любых изменениях, внесенных другим приложением, если оно не использует кеш? Единственная возможность, оставленная провайдеру кэша / JPA, состоит в том, чтобы отслеживать базу данных (все таблицы, все данные) на предмет изменений и обновлять соответственно. Это не реально осуществимо.

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

1 голос
/ 13 ноября 2013

Мы успешно использовали PostgreSQL LISTEN / NOTIFY, чтобы поддерживать наши кэши второго уровня (на стороне клиента) в актуальном состоянии. Начиная с PostgreSQL 9.0, NOTIFY также поддерживает указание полезной нагрузки. Мы реализовали это в C ++ и использовали ODBC, но JPA / JDBC также предоставляют такие возможности.

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

Суть процедуры:

  1. Реализация кэша LISTEN s для конкретного события (например, "MYTABLE")
  2. Опубликовать триггеры вставки / обновления / удаления MYTABLE записать изменения (например, метку времени события, код операции и первичный ключ) в таблицу MYTABLE_NY и отправить уведомление: NOTIFY MYTABLE
  3. Реализация кэша получает уведомление и проверяет последние изменения (например, EVENT_TIMESTAMP > last_cache_refresh) в MYTABLE_NY.
  4. Для каждого события он удаляет данный экземпляр из кэша. В случае Hibernate, используя session.evict() или cache.evictEntity()

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

Я могу предоставить некоторые примеры кода, если интересно.

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