在做大批量處理時,容易出現outofmemory的情況,分析及解決如下
(1)原因
?當首次作Insertupdatedeleteselect時,新產生的object在session關閉之前將自動裝載到session級別的緩存區,如果,AP使用了二級緩存,同樣也會裝入到二級緩存。所以當數據量大時,就會出現outofmemory情況。
?
(2)解決方法
?
(A)批量插入(Batch inserts)/批量更新(Batch updates)
必須通過經常的調用 flush() 以及稍后調用 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批量設置相同
??????? //flush a batch of inserts and release memory:
??????? //將本批插入的對象立即寫入數據庫并釋放內存
??????? session.flush();
??????? session.clear();
??? }
}
??
tx.commit();
session.close();
?
(B)大批量更新/刪除(Bulk update/delete)
使用HQL語言
?
執行一個HQL DELETE,同樣使用 Query.executeUpdate() 方法 (此方法是為 那些熟悉JDBC PreparedStatement.executeUpdate() 的人們而設定的)
(1)原因
?當首次作Insertupdatedeleteselect時,新產生的object在session關閉之前將自動裝載到session級別的緩存區,如果,AP使用了二級緩存,同樣也會裝入到二級緩存。所以當數據量大時,就會出現outofmemory情況。
?
(2)解決方法
?
(A)批量插入(Batch inserts)/批量更新(Batch updates)
必須通過經常的調用 flush() 以及稍后調用 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批量設置相同
??????? //flush a batch of inserts and release memory:
??????? //將本批插入的對象立即寫入數據庫并釋放內存
??????? 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();
執行一個HQL DELETE,同樣使用 Query.executeUpdate() 方法 (此方法是為 那些熟悉JDBC PreparedStatement.executeUpdate() 的人們而設定的)
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();