Будьте в спящем режиме кэш запроса - для объектов не в 2-м кэше уровня - опасный? полезный? плохая практика?

Связанный с этим вопросом

Предпосылка:

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

  • Кэш запроса хорош главным образом наряду с 2-м кэшем уровня
  • Кэш запроса кэширует результаты идентификаторов запросов + параметры
  • Кэш запроса опасен, если база данных была изменена, и это не было отражено к кэшу

Вопрос:

У меня есть объект, который не находится в 2-м кэше уровня. Из-за некоторого плохого программирования или других ограничений, код, который загружает объект, называют, несколько времен в том же в спящем режиме сессия. retrival использует HQL, находят запрос, например.

 hibernateTemplate.find("from Foo f where f.bar > ?", bar);

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

Затем я хотел видеть то, что происходит, если я добавляю кэш запроса:

 Query query = session.createQuery("from Foo f where f.bar > ?");
 query.setCacheable(true);
 query.setParameter(bar);
 query.list();

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

  1. Таким образом, мое первое предположение, это В спящем режиме первые поиски в Кэше Сессии, затем в 2-м Кэше Уровня. Это предположение корректно?
  2. Я также предполагаю что если объект (Foo) то, которое не находится в 2-м кэше уровня, было изменено в базе данных, затем запросите кэш, будучи перекрестной ограниченной по объему сессией, возвратит неправильные идентификаторы и таким образом неправильные объекты. Это корректно?
  3. Затем безопасно сказать, что использование кэша запроса для запросов, которые включают неизменную информацию даже для не 2L кэшируемые объекты, является хорошей практикой? (например, запрос, которые, где пункт содержит условие, которое будет всегда возвращать те же результаты, например, "выбирают p.ser_num где p.id =?" когда ser_num и идентификационные пары не изменяются когда-то созданный),

Между прочим, в связанном вопросе утверждается, что кэш запроса не работает над объемом Кэша Сессии. Я неправильно понимаю то требование или что-либо еще?

10
задан Community 23 May 2017 в 12:00
поделиться

3 ответа

Кэш запросов - это особый тип кеша 2-го уровня. То, что вы называете кешем 2-го уровня, я бы предпочел называть «кешем объектов».

Комментарии к вашим предположениям:

  • Кэш запросов хорош в основном вместе с кешем 2-го уровня (он же объект кеш).

Кэш запросов содержит только необработанные результаты запросов в качестве первичных ключей, в спящем режиме, идентификаторов. Он не удерживает фактические гидратированные объекты. Это имеет смысл, поскольку когда вы выполняете запрос с помощью jdbc, он фактически возвращает вам гидратированные (заполненные) объекты, когда вы выполняете итерацию по ResultSet. Заявление не обязательно правильное. Если запрос очень сложен и, следовательно, требует очень много времени для выполнения, используя кеш запроса, вы сэкономите это время. Используя кеш запросов, вы не сэкономите время, необходимое для загрузки объектов из базы данных.

  • Кэш запросов опасен, если база данных была изменена, и это не отразилось в кэш

Это верно, но это не уникально для кеша запросов, то же самое верно и для того, что вы называете кешем 2-го уровня, но что обычно называется кешем объектов.

Итак, мое первое предположение состоит в том, что Hibernate первые поиски в Сессионный кеш, затем на 2-м уровне Кэш. Верно ли это предположение?

Да, при загрузке объектов происходит такое поведение.

Я также предполагаю, что если объект (Foo) которого нет в кеше 2-го уровня, был изменен в базе данных, затем кеш запросов, являющийся перекрестным сеансом ограниченный, вернет неправильный идентификаторы, и, следовательно, неправильные объекты. Это правильно?

Да, это затронет как кеш объектов, так и кеш запросов. Это вызывает беспокойство только в том случае, если база данных изменяется без перехода в спящий режим. Вы можете уменьшить влияние этого, установив тайм-аут кеша запросов.

Можно ли тогда сказать, что использование кеш запросов для запросов, которые включают неизменяемая информация даже для не 2L кэшированные объекты, это хорошая практика? (например, запрос, в котором его предложение where содержит условие, которое всегда будет вернуть те же результаты, например "Выбрать p.ser_num, где p.id =? "когда ser_num и id пары не меняются ни разу created)

Для таких объектов нет причин не использовать как кеш объектов, так и кеш запросов.

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

7
ответ дан 4 December 2019 в 01:31
поделиться

Для вопроса #3 я не думаю, что вы хотите использовать кэш запросов, когда объекты не кэшируются. Вы получите все первичные идентификаторы, но для получения объектов, которые могут быть медленнее, чем выполнение запроса без кэширования вообще, придется один раз ударять по базе данных по каждому ключу. В любом случае, начиная с версии 3.3, может быть, в более новых версиях он хватает недостающие объекты, используя меньшее количество запросов, например, where id в (:id1,:id2,...).

.
1
ответ дан 4 December 2019 в 01:31
поделиться

только предположения:

Согласно этой статье из документации Hibernate:

.

[кэш запросов] создает два новых кэша. регионы: один запрос с кэшированием наборы результатов (org.hibernate.cache.StandardQueryCache), другие временные метки последние обновления для запрашиваемых таблицы (org.hibernate.cache.UpdateTimestampsCache).

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

Но 2 предложения позже в том же параграфе документации говорится:

Кэш запросов должен всегда использоваться в связи со вторым уровнем кэш

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

.
2
ответ дан 4 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: