我正在使用Hibernate 5.2.8.Final版本,我们有一个要求,我们从数据库中读取数百万个数据并通过某些业务逻辑更新数据,因为我的数据库是巨大的我想在达到批量化后提交数据所以我写了下面的代码
synchronized
以下是我的Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.getTransaction().begin();
Query<Object> query = session.createQuery(SQL, Object.class);
ScrollableResults scrollableResults = query.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count = 0;
while (scrollableResults.next())
{
Object object = (Object) scrollableResults.get(0);
process(object)
session.update(object);
if (++count % batchSizeDeclare== 0)
{
session.flush();
session.clear();
LOGGER.info("Updated batch records");
}
}
session.getTransaction().commit();
LOGGER.info("commited in Hibernate ");
}
文件
hibernate.cfg.xml
以下是我的<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://com;database=DEV</property>
<property name="connection.username">user</property>
<property name="connection.password">pass</property>
<property name="hibernate.default_schema">schema</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">5</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.SQLServer2012Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<!-- <property name="show_sql">true</property> -->
<!-- <property name="format_sql">true</property> -->
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.jdbc.batch_size">100</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<mapping class="com.beans.Object" />
</session-factory>
</hibernate-configuration>
Object.java
一旦我的代码到达session.flush(),即使在等待30分钟后也没有做任何事情。这是批量提交的正确方法吗?如何批量更新?
答案 0 :(得分:0)
一旦我的代码到达session.flush,它甚至没有做任何事情 等了30分钟后。
恰恰相反!数据库做得太多了。只是你没有看到任何进展,因为数据库正在努力应对你提交的大量工作。
这是批量提交的正确方法吗?
简短的回答是否。
正如我在文章14 High-Performance Java Persistence Tips中所解释的那样,您不必从数据库中获取数百万行。你有更好的选择:
解决问题的唯一方法就是改变方法。