反復の前にトランザクションを開始し、その後、単一のトランザクション内でそれをコミットしてみることができます。したがって、基本的には、コミット時にマージ/永続化されるバッチを作成しています。
また、一度に処理されるバッチ内のオブジェクトの数を制限し、変更をデータベースに明示的にフラッシュすることができます。
ここでは、トランザクションを開始して各反復でコミットし、そのたびにエンティティマネージャーを作成/終了すると、多数のデータのパフォーマンスに影響します。
以下のコードのようになります。
em = factory.createEntityManager();
em.getTransaction().begin();
int i = 0;
for (Object ob : list) {
Long start = Calendar.getInstance().getTimeInMillis();
em.merge(ob);
Long end = Calendar.getInstance().getTimeInMillis();
Long diff = end - start;
LOGGER.info("Time: " + diff);
/*BATCH_SIZE is the number of entities
that will be persisted/merged at once */
if(i%BATCH_SIZE == 0){
em.flush();
em.clear();
}
i++;
}
em.getTransaction().commit();
em.close();
ここでは、オブジェクトのいずれかが永続化/マージに失敗した場合に、トランザクション全体をロールバックすることもできます。