如何使用会话工厂提高批量插入的性能

时间:2012-12-08 00:01:33

标签: java hibernate session seam

我正在使用jpa和hibernate一起使用seam。我一次只能插入200,000条记录。

这是我的代码:

的hibernate.cfg.xml

<hibernate-configuration>
 <session-factory name="java:/mobeeSessionFactory">
  <property name="hibernate.connection.pool_size">10</property>
  <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
  <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:mobee</property>
  <property name="hibernate.connection.username">mobeemigrate</property>
  <property name="hibernate.connection.password">mobeemigrate</property>
  <property name="hibernate.show_sql">false</property>
  <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
  <property name="hibernate.format_sql">false</property>
  <property name="hibernate.hbm2ddl.auto">update</property>
  <property name="hibernate.session_factory_name">java:/mobeeSessionFactory</property>
  <property name="hibernate.connection.datasource">mobeeadminDataSource</property>
  <property name="hibernate.jdbc.batch_size">10000</property>
  <property name="hibernate.cache.use_first_level_cache">true</property>
  <property name="hibernate.cache.use_second_level_cache">false</property>
  <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
  <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
  <property name="hibernate.transaction.auto_close_session">false</property>
  <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
  <property name="hibernate.transaction.flush_before_completion">true</property>

  <!-- Here are the mappings -->
  <mapping package="com.manam.mobee.persist.entity"/>
  <mapping class="com.manam.mobee.persist.entity.TempCustomers"/>
  <mapping class="com.manam.mobee.persist.entity.TempAccounts"/>
 </session-factory>

component.xml文件

<persistence:hibernate-session-factory name="hibernateSessionFactory" cfg-resource-name="hibernate.cfg.xml"/>
    <persistence:managed-hibernate-session name="session" 
                 auto-create="true"
     session-factory-jndi-name="java:/mobeeSessionFactory"/>

示例代码:

 Session session =hibernateSessionFactory.openSession();
             Transaction tx = session.beginTransaction();

   for(int i=0;i<doTempAccounts.size();i++){

     try {
    TempAccounts temp=new TempAccounts();

    BeanUtils.copyProperties(temp, doTempAccounts.get(i));

    session.save(temp);

    if ( i % 10000 == 0 ) { //10000, same as the JDBC batch size
     //flush a batch of inserts and release memory:
    log.info("********** Batch Updates**********");
    session.flush();
    session.clear();
     }
     }
     }
    tx.commit();
    session.close();

以上代码正常运行,但插入200,000条记录大约需要10分钟。我的代码中是否有任何配置可以提高批量插入的性能?

在上面的代码中,我每隔10000条记录执行一次session.flush(),但每次都不插入数据库。你能解释一下如何对db执行批量插入吗?

3 个答案:

答案 0 :(得分:1)

  

在上面的代码中,我每10000条记录执行一次session.flush(),但每次都没有插入数据库。

我认为你的意思是在你到达终点之前,记录似乎并不存在;即它们不会出现在不同交易中的查询中。

如果这是你的意思,那么解释很简单。您正在单个事务中执行插入操作,并且只有在事务提交时才会显示记录...最后。如果您需要将插入更快地显示,请尝试将插入拆分为多个事务


您还应该阅读有关批处理操作的Hibernate文档 - http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html。我注意到它说合理的批量大小是20到50 ......而不是10000.它还提到了直接使用SQL进行批量数据操作和StatelessSession的方法。

以下是另一种特定于插入的资源,其中包含StatelessSession的插入:http://javainnovations.blogspot.com.au/2008/07/batch-insertion-in-hibernate.html

答案 1 :(得分:1)

查看StatelessSession以及如何使用它将项目插入数据库。当问到这个问题时,这似乎是回答的问题,我个人只是用它在15秒内完成了15分钟的工作。它并不适合所有情况,但如果确实如此,那就很有效。

答案 2 :(得分:0)

您可以像在SQL中一样执行此操作。请看以下HQL示例:

insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...

参考:http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch04.html#d0e2184