在做大批量處理時,容易出現(xiàn)outofmemory的情況,分析及解決如下
(1)原因
?當(dāng)首次作Insertupdatedeleteselect時,新產(chǎn)生的object在session關(guān)閉之前將自動裝載到session級別的緩存區(qū),如果,AP使用了二級緩存,同樣也會裝入到二級緩存。所以當(dāng)數(shù)據(jù)量大時,就會出現(xiàn)outofmemory情況。
?
(2)解決方法
?
(A)批量插入(Batch inserts)/批量更新(Batch updates)
必須通過經(jīng)常的調(diào)用 flush() 以及稍后調(diào)用 clear() 來控制第一級緩存的大小
如:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
??
for ( int i=0; i<100000; i++ ) {
??? Customer customer = new Customer(.....);
??? session.save(customer);
??? if ( i % 20 == 0 ) {
//20, same as the JDBC batch size //20,與JDBC批量設(shè)置相同
??????? //flush a batch of inserts and release memory:
??????? //將本批插入的對象立即寫入數(shù)據(jù)庫并釋放內(nèi)存
??????? session.flush();
??????? session.clear();
??? }
}
??
tx.commit();
session.close();
?
(B)大批量更新/刪除(Bulk update/delete)
使用HQL語言
?
執(zhí)行一個HQL DELETE,同樣使用 Query.executeUpdate() 方法 (此方法是為 那些熟悉JDBC PreparedStatement.executeUpdate() 的人們而設(shè)定的)
(1)原因
?當(dāng)首次作Insertupdatedeleteselect時,新產(chǎn)生的object在session關(guān)閉之前將自動裝載到session級別的緩存區(qū),如果,AP使用了二級緩存,同樣也會裝入到二級緩存。所以當(dāng)數(shù)據(jù)量大時,就會出現(xiàn)outofmemory情況。
?
(2)解決方法
?
(A)批量插入(Batch inserts)/批量更新(Batch updates)
必須通過經(jīng)常的調(diào)用 flush() 以及稍后調(diào)用 clear() 來控制第一級緩存的大小
如:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
??
for ( int i=0; i<100000; i++ ) {
??? Customer customer = new Customer(.....);
??? session.save(customer);
??? if ( i % 20 == 0 ) {
//20, same as the JDBC batch size //20,與JDBC批量設(shè)置相同
??????? //flush a batch of inserts and release memory:
??????? //將本批插入的對象立即寫入數(shù)據(jù)庫并釋放內(nèi)存
??????? session.flush();
??????? session.clear();
??? }
}
??
tx.commit();
session.close();
?
(B)大批量更新/刪除(Bulk update/delete)
使用HQL語言
?
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlUpdate = "update Customer set name = :newName where name = :oldName"; int updatedEntities = s.createQuery( hqlUpdate ) .setString( "newName", newName ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit(); session.close();
執(zhí)行一個HQL DELETE,同樣使用 Query.executeUpdate() 方法 (此方法是為 那些熟悉JDBC PreparedStatement.executeUpdate() 的人們而設(shè)定的)
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlDelete = "delete Customer where name = :oldName"; int deletedEntities = s.createQuery( hqlDelete ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit(); session.close();