第14章 バッチ処理
Hibernate を使ってデータベースに10万行を挿入する愚直な方法は、このようなものです:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
}
tx.commit();
session.close();
これは50,000番目の行のあたりで
OutOfMemoryException で失敗するでしょう。Hibernate がセッションレベルキャッシュで、新しく挿入されたすべての Customer インスタンスをキャッシュするからです。この章で、こういう問題を回避する方法を説明します。
バッチ処理をするなら、JDBC バッチが使用可能であることが非常に重要です。そうでなければ手頃なパフォーマンスが得られません。JDBC バッチサイズを手頃な数値(例えば、10から50)に設定してください:
hibernate.jdbc.batch_size 20
identiy 識別子生成を使う場合は、Hibernate は JDBC レベルでインサートバッチングを無効にします。
また二次キャッシュとの相互作用が完全に無効になっているプロセスで、このような作業をしたいと思うかもしれません:
hibernate.cache.use_second_level_cache false
しかし、これは絶対に必要というわけではありません。なぜなら明示的に
CacheMode を設定して、二次キャッシュとの相互作用を無効にすることができるからです。
14.1. バッチ挿入 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
新しいオブジェクトを永続化する場合、一次キャッシュのサイズを制限するため、定期的にセッションを
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
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();