如何防止Hibernate在列表中刷新? [英] How to prevent Hibernate from flushing in list?

查看:113
本文介绍了如何防止Hibernate在列表中刷新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的Hibernate查询,如:

  from MyEntity where name =? 

没什么特别的,但是它在一个相当大的交易中多次被调用(持续一秒钟,可能会加载几十次或数百个实体)。 Profiler显示花费了大量时间:

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


我可以以某种方式阻止Hibernate执行此flush操作?



如果不是,我该怎么做才能让它更快?

解决方案

默认情况下,在会话期间发出查询(FlushMode.AUTO)之前,hibernate会刷新并咀嚼大量的CPU时间。如果您有一个会话,许多查询和更新交替运行,那就特别痛苦。



如果查询可能选择在当前会话期间插入/更新/删除的数据,则需要这些刷新。即使您没有修改当前事务中的任何内容,但使用事务隔离级别(如read-uncommitted),也可以这样做。



假设您不想要未提交的阅读等,我知道有两种方法:


  1. 选择所有内容您需要在会话之前进行任何修改(即重新排序,以便所有查询在发生任何修改之前发布)。

  2. 如果您确定要选择在此会话中未修改的数据,那么您可以明确地将flush模式设置为不会触发flush的内容,如下所示:

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



I have a simple Hibernate query like:

from MyEntity where name = ?

Nothing fancy, but it's called many times in a fairly big transaction (lasts one second, may load dozens or hundreds of entities). Profiler shows that a lot of time is spent in:

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

In other words - flushing changes before running the actual query.

Can I somehow prevent Hibernate from doing this flush at all?

If not, what can I do to make it faster?

解决方案

By default hibernate flushes before issuing a query during a session (FlushMode.AUTO), and chews up lots of CPU time doing it. It is particularly painful if you have a session where many queries and updates run alternately.

If the query is likely to select back data that you have inserted/updated/deleted during the current session then you need these flushes. This may also be the case even if you haven't modified anything in the current transaction but are using a transaction-isolation level like read-uncommitted.

Assuming you don't want uncommitted reads, etc., there are two ways around this that I know of:

  1. Select everything you'll need during the session before you make any modifications (ie., re-order things so that all your queries are issued before any modifications are made).
  2. If you know for sure that you are selecting data that has not been modified in this session then you can explicitly set the flush-mode to something which won't trigger the flush, like this:

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

这篇关于如何防止Hibernate在列表中刷新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆