Java Hibernate批处理的用途是什么
我不熟悉hibernate我对hibernate批处理有疑问,我读了一些关于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
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;},我可以使用吗?当然可以,但这不是最优的。批量大小应该匹配。非常感谢,我现在清楚这个概念了。刚刚找到一篇关于的文章刚刚找到一篇关于的文章