【问题标题】:Hibernate batch update doesn't work休眠批量更新不起作用
【发布时间】:2012-01-01 11:55:08
【问题描述】:

我想使用休眠批量更新,我尝试了批量插入,它工作正常,这是我用于休眠的配置

<property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                hibernate.hbm2ddl.auto=update
                hibernate.show_sql=false
                hibernate.jdbc.fetch_size=100
                hibernate.jdbc.batch_size=100
                hibernate.jdbc.batch_versioned_data=true
                hibernate.order_inserts=true
                hibernate.order_updates=true
                hibernate.cache.use_query_cache=false
                hibernate.cache.use_second_level_cache=false

            </value>
        </property>

这是 DAO 代码:

public void updateBulkEmployees(List<Employee> employees) throws Exception {

        for (int i = 0; i < employees.size(); i++) {
            sessionFactory.getCurrentSession().update(employees.get(i));
            if (i % 100 == 0) {
                sessionFactory.getCurrentSession().flush();
                sessionFactory.getCurrentSession().clear();
                log.debug("Flushing batch:" + (int) (i / 100));
            }            

        }

            sessionFactory.getCurrentSession().flush();
            sessionFactory.getCurrentSession().clear();

    }

问题:我注意到方法执行花费了很多时间(与不使用批处理所花费的时间完全相同),所以批处理更新不起作用,我是否缺少配置或正在做的事情有事吗 ? 请指教,谢谢。

【问题讨论】:

  • 仅仅因为它需要相同的时间并不意味着更新不是批处理的。这也可能意味着使用了批处理,但根本不会让事情变得更快。
  • 所以你的意思是上面的配置没有问题,还是只能改进或调整更多?
  • @JB Nizet,在这种情况下如何让事情变得更快,你有什么建议?
  • 确实,我看不出有什么问题。您必须进行分析,然后进行实验,以了解缓慢的来源。可能是网络、数据库、索引过多、内存不足……

标签: hibernate jakarta-ee


【解决方案1】:

你怎么知道批量插入有效?观看 mysql.log 是了解批量插入/更新是否有效的唯一方法(即使使用批量,Hibernate 也始终记录单个查询)。

要在 MySQL 中使用批处理,您必须在 URL 中设置特定的 JDBC 参数(Hibernate 批处理使用 JDBC 批处理功能)。尝试:

http://your_host:your_port/database?rewriteBatchedStatements=true

并且不要使用 GenerationType.AUTO 或 GenerationType.IDENTITY 作为 ID 生成器。在这种情况下,Hibernate 会以静默方式禁用批处理功能。

提示:只有在避免 OutOfMemory 时才需要中间刷新。 Hibernate 尝试尽可能最后查询数据库,因此如果您尝试更新 1000000 个实体,它会将所有实体保留在内存中直到提交。

【讨论】:

    【解决方案2】:

    不应该是第二个“sessionFactory.getCurrentSession().flush();”在循环之外?

    【讨论】:

      猜你喜欢
      • 2021-10-02
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 2014-02-12
      • 1970-01-01
      • 2014-10-07
      • 2014-06-10
      • 2015-08-03
      相关资源
      最近更新 更多