Как предотвратить Hibernate от промывки в списке?

у меня есть простой запрос Hibernate, например:

from MyEntity where name = ?

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

org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1185)
org.hibernate.internal.SessionImpl.list(SessionImpl.java:1240)
org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)

другими словами-изменения промывки перед запуском фактического запроса.

могу ли я как-то предотвратить спящий режим от этого флеш-памяти вообще?

Если нет, что я могу сделать, чтобы сделать это быстрее?

1 ответов


по умолчанию hibernate сбрасывает перед выдачей запроса во время сеанса (FlushMode.AUTO), и жует много времени процессора, делая это. Это особенно болезненно, если у вас есть сеанс, где много запросов и обновлений выполняются поочередно.

если запрос, скорее всего, выберет данные, которые вы вставили/обновили/удалили во время текущего сеанса, вам понадобятся эти сбросы. Это мая также будет иметь место, даже если вы ничего не изменили в текущей транзакции но используют уровень изоляции транзакций, такой как Read-uncommitted.

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

  1. выберите все, что вам нужно во время сеанса до вы делаете любые изменения (т. е., переупорядочить вещи, чтобы все ваши запросы были выпущены до внесения каких-либо изменений).
  2. Если вы точно знаете, что вы выбираете данные, которые не были изменено в этом сеансе, тогда вы можете явно установить режим flush на что-то, что не вызовет flush, например:

    Query query = session.getNamedQuery(SOME_QUERY_NAME);
    query.setFlushMode(FlushMode.COMMIT);