Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate批处理的用途是什么_Java_Hibernate_Batch Processing - Fatal编程技术网

Java Hibernate批处理的用途是什么

Java Hibernate批处理的用途是什么,java,hibernate,batch-processing,Java,Hibernate,Batch Processing,我不熟悉hibernate我对hibernate批处理有疑问,我读了一些关于hibernate批处理的教程 Session session = SessionFactory.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Employee employee = new Employee(.....); session.save(employee

我不熟悉hibernate我对hibernate批处理有疑问,我读了一些关于hibernate批处理的教程

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) 
{
  Employee employee = new Employee(.....);
  session.save(employee);

}
tx.commit();
session.close();
Hibernate将在会话级缓存中缓存所有持久化对象,最终应用程序将在第50000行的某个位置出现OutOfMemoryException。如果使用Hibernate之类的批处理,则可以解决此问题

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) 
{
 Employee employee = new Employee(.....);
 session.save(employee);
 if( i % 50 == 0 ) 
 { // Same as the JDBC batch size
   //flush a batch of inserts and release memory:
   session.flush();
   session.clear();
 }
}
tx.commit();
session.close();
我的疑问是,与其在外部初始化会话,不如在for循环中初始化它

Session session = null;
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) 
{
 session =SessionFactory.openSession()
 Employee employee = new Employee(.....);
 session.save(employee);
}
tx.commit();
session.close();

这是正确的方式还是没有人建议我正确的方式?

没有。不要在for循环中初始化会话;每次启动一个新会话时,您都在启动一个新的批处理,因此批处理大小是您的方式之一,即非批处理。而且,你的方式会慢得多。这就是为什么第一个例子

if( i % 50 == 0 ) { 
  //flush a batch of inserts and release memory:
  session.flush();
  session.clear();
}

这就是刷新一批插入和释放内存的目的。

否。不要在for循环中初始化会话;每次启动一个新会话时,您都在启动一个新的批处理,因此批处理大小是您的方式之一,即非批处理。而且,你的方式会慢得多。这就是为什么第一个例子

if( i % 50 == 0 ) { 
  //flush a batch of inserts and release memory:
  session.flush();
  session.clear();
}
这就是刷新一批插入和释放内存的目的。

Hibernate中的批处理意味着将大量任务划分为一些较小的任务

当您启动session.saveobj时,hibernate实际上会将该对象缓存到其内存中,但该对象尚未写入数据库,并且在提交事务时(即调用transaction.commit时)会将其保存到数据库中

假设您有数百万条记录要插入,因此触发session.saveobj会消耗大量内存,最终会导致OutOfMemoryException

解决方案: 创建一个较小的简单批并将其保存到数据库

if( i % 50 == 0 ) { 
  //flush a batch of inserts and release memory:
  session.flush();
  session.clear();
}
注: 在上面的代码中,session.flush将刷新,即实际将对象保存到数据库和session中。clear将清除这些对象占用的所有内存,以便批量大小为50。

Hibernate中的批处理意味着将大量任务划分为一些较小的任务

当您启动session.saveobj时,hibernate实际上会将该对象缓存到其内存中,但该对象尚未写入数据库,并且在提交事务时(即调用transaction.commit时)会将其保存到数据库中

假设您有数百万条记录要插入,因此触发session.saveobj会消耗大量内存,最终会导致OutOfMemoryException

解决方案: 创建一个较小的简单批并将其保存到数据库

if( i % 50 == 0 ) { 
  //flush a batch of inserts and release memory:
  session.flush();
  session.clear();
}
注:
在上面的代码中,session.flush将刷新,即实际将对象保存到数据库中,session.clear将清除这些对象占用的所有内存,以便批量大小为50。

批处理允许您优化写入数据

但是,通常关于刷新和清除Hibernate会话的建议是不完整的

您需要在批处理结束时提交事务,以避免可能影响性能的长时间运行的事务,如果最后一项失败,撤消所有更改将给数据库带来很大压力

因此,您应该这样做批量处理:

int entityCount = 50;
int batchSize = 25;

EntityManager entityManager = entityManagerFactory().createEntityManager();

EntityTransaction entityTransaction = entityManager.getTransaction();

try {
    entityTransaction.begin();

    for (int i = 0; i < entityCount; i++) {
        if (i > 0 && i % batchSize == 0) {
            entityTransaction.commit();
            entityTransaction.begin();

            entityManager.clear();
        }

        Post post = new Post(
            String.format("Post %d", i + 1)
        );
        
        entityManager.persist(post);
    }

    entityTransaction.commit();
} catch (RuntimeException e) {
    if (entityTransaction.isActive()) {
        entityTransaction.rollback();
    }
    throw e;
} finally {
    entityManager.close();
}

批处理允许您优化写入数据

但是,通常关于刷新和清除Hibernate会话的建议是不完整的

您需要在批处理结束时提交事务,以避免可能影响性能的长时间运行的事务,如果最后一项失败,撤消所有更改将给数据库带来很大压力

因此,您应该这样做批量处理:

int entityCount = 50;
int batchSize = 25;

EntityManager entityManager = entityManagerFactory().createEntityManager();

EntityTransaction entityTransaction = entityManager.getTransaction();

try {
    entityTransaction.begin();

    for (int i = 0; i < entityCount; i++) {
        if (i > 0 && i % batchSize == 0) {
            entityTransaction.commit();
            entityTransaction.begin();

            entityManager.clear();
        }

        Post post = new Post(
            String.format("Post %d", i + 1)
        );
        
        entityManager.persist(post);
    }

    entityTransaction.commit();
} catch (RuntimeException e) {
    if (entityTransaction.isActive()) {
        entityTransaction.rollback();
    }
    throw e;
} finally {
    entityManager.close();
}

哦好的,谢谢,如果我使用30,我还有一个疑问,如果我%50==0{session.flush;session.clear;},我可以使用吗?当然可以,但这不是最优的。批量大小应该匹配。非常感谢你,现在我清楚这个概念了。哦!好的,谢谢,如果我使用30,我还有一个疑问,如果我%50==0{session.flush;session.clear;},我可以使用吗?当然可以,但这不是最优的。批量大小应该匹配。非常感谢,我现在清楚这个概念了。刚刚找到一篇关于的文章刚刚找到一篇关于的文章