创建实现 Runnable 的新线程,以使用 JPA/Hibernate 提高批量插入 Oracle 的性能

问题描述

我目前在使用 EntityManager 提供的 executeUpdate() 方法向 oracle 插入数据时遇到速度缓慢的问题。我的应用程序在给定时间可能有几十万条记录要插入到 Oracle 中,我正在努力使性能尽可能快速/高效。我的想法是一次为 5000 条记录实现 Runnable,这样我就可以为每个 5000 条记录执行并发线程。我不确定如何实现这一点,但我认为能够使用 Hibernate/JPA 将批量数据插入到 Oracle 中。

这是我的 DAO 方法,它在我循环传递的列表中保留数据:

public void insertPromoData(List<InsertPromoData> insertData) {
          EntityManager em = emf.createEntityManager();
                  
          try {
              //EntityManager em = emf.createEntityManager();
              System.out.println("Beginning insertPromoData at " + System.currentTimeMillis());
              em.getTransaction().begin();
              int count = 0;
              int sequenceCount = 0;
              Query query = em.createNativeQuery(env.getProperty("insertPromoUploadData"));
              if (!(getMaxSequenceNum() == null)) {
                  sequenceCount = getMaxSequenceNum().intValue() + 1;
              }
              else {
                  sequenceCount = 1;
              }
              for (InsertPromoData promoData : insertData) {
                  query.setParameter("id",(new Long(sequenceCount)));
                  query.setParameter("item",promoData.getItem());
                  query.setParameter("location",promoData.getLoc());
                  query.executeUpdate();
                  ++count;
                  ++sequenceCount;
                  if (count > 0 && count % 1000 == 0) {
                    em.getTransaction().commit();
                    em.clear();
                    em.getTransaction().begin();
                  }
              }
              em.getTransaction().commit();
          }
          catch(Exception e) {
              logger.error("Exception in beginning transaction");
              e.printstacktrace();
          }
          finally {
              em.clear();
              em.close();
          }  
          logger.debug("Execution of method insertPromoData in Dao ended");
}

这是我正在执行的查询(来自属性文件):

insertPromoUploadData = INSERT INTO SCHEMA.PROMO (SEQ_NUM,ITEM,LOC,U_TIMESTAMP) VALUES (:id,:item,:location,SYSDATE)

getMaxPromovalue = SELECT MAX(SEQ_NUM) FROM SCHEMA.PROMO

我的实体:

@Entity
@Table(name = "U_USER_PROMO")
public class InsertPromoData {

    @Id
    @Column(name="SEQ_NUM")
    Long id;

    @Column(name="ITEM")
    String item;
    
    @Column(name="LOC")
    String loc;

    //getters and setters

我虽然在开始时实现了一个新线程:

if (count > 0 && count % 1000 == 0) {
    em.getTransaction().commit();
    em.clear();
    em.getTransaction().begin();
}

关于如何执行此操作或提高插入性能的任何建议? 9000 条记录需要 7-8 分钟,这太慢了。我不确定是什么导致了这种缓慢。任何帮助表示赞赏。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...