【问题标题】:How do I perform batch insert with Playframewok JPA?如何使用 Playframewok JPA 执行批量插入?
【发布时间】:2011-07-30 10:03:16
【问题描述】:

我需要解析一个非常大的文件并将生成的实体存储在数据库中。 我预计每个文件最多有 15 万条记录,并且可能会批量处理这些记录。

有没有办法用 JPA 批量插入 Play 实体?

【问题讨论】:

    标签: java hibernate jpa playframework


    【解决方案1】:

    为了节省内存,您必须确保定期清除会话,所以

    Customer.em().getTransaction().begin(); 
    for ( int i=1; i<=100000; i++ ) {
       ....
       myCustomer.save();
       if (i%1000==0) { 
           //Customer.em().getTransaction().commit();           
           Customer.em().flush(); 
           Customer.em().clear();
           //Customer.em().getTransaction().begin(); 
       }
    }
    Customer.em().getTransaction().commit();           
    

    如果您优化批量大小,您将如何提高性能 hibernate.jdbc.batch_size 100

    您可以简单地将最后一行添加到application.conf,所有hibernate.* 属性直接进入hibernate。详情见JPAPlugin的代码。

    【讨论】:

    • 感谢您的回复。在提交和开始之后刷新和清除是否重要?如果每 1000 次迭代提交一次事务,休眠批量大小 = 100 的影响是什么?
    • 嗯我觉得你是对的,你不需要处理交易。冲洗干净就足够了。关于批量大小:据我所知,这决定了有多少语句直接发送到数据库。这意味着从 1 开始的批大小是网络 io 的 1000 倍,如果要插入 1000 个条目,则为 100 时只有 10 个。
    • 批量大小会影响应用程序实体的生命周期吗?即批量大小为 100 调用 MyEntity.save() 是否意味着它们实际上每 100 次才持久化?
    • 好吧 MyEntity.save() 只在休眠中设置一个标志。仅刷新将其发送到数据库。但我不确定 jdbc-driver 是否会再次缓存。我只有普通 jdbc 的 fetchsize 经验,它的默认值非常小。如果增加它会对性能产生很大影响。所以我建议做一些测试,看看内存消耗和持续时间。
    【解决方案2】:

    由于 Play 在后台使用 Hibernate,您应该能够使用 Hibernate 使用的标准批处理。见http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html

    但是,Play 会自动为您管理事务,因此,如果您需要防止 Play 干扰事务管理,您可以使用 @play.db.jpa.NoTransaction 注释您的方法。

    您可以在此处http://www.playframework.org/documentation/1.2.1/jpa 阅读有关 Play 的 JPA 和事务支持的更多信息

    【讨论】:

    • 处理发生在 Job 中,我不确定是否可以应用 @NoTransaction。我尝试每 1000 次迭代调用以下行,这似乎给了我恒定的时间/内存/处理:Customer.em().getTransaction().commit(); Customer.em().getTransaction().begin();客户.em().flush(); Customer.em().clear();
    猜你喜欢
    • 2010-10-01
    • 2023-04-03
    • 2010-09-09
    • 1970-01-01
    • 2014-11-14
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多