3

MySQL 5.0 DB を備えた WebSphere Application Server 8 で OpenJPA 2.2.0 を使用しています。

DB にマージしたいオブジェクトのリストがあります。

それは次のようなものです:

for (Object ob : list) {
            Long start = Calendar.getInstance().getTimeInMillis();
            em = factory.createEntityManager();
            em.getTransaction().begin();

            em.merge(ob);

            em.getTransaction().commit();
            em.close();
            Long end = Calendar.getInstance().getTimeInMillis();
            Long diff = end - start;
            LOGGER.info("Time: " + diff);
        }

このループを実行すると、1 つのオブジェクトをマージするのに約 300 ~ 600 ミリ秒かかります。「em.merge(ob);」という行を削除すると 次に、1つのリストオブジェクトを反復処理するには「0」ミリ秒が必要です。

だから私の質問は: 1 つのオブジェクトをマージする時間を改善するにはどうすればよいですか?

ありがとう!

4

1 に答える 1

7

反復の前にトランザクションを開始してから、単一のトランザクション内で後でコミットすることができます。したがって、基本的には、コミット時にマージ/永続化されるバッチを作成しています。

また、一度に処理するバッチ内のオブジェクトの数を制限したり、変更を明示的にデータベースにフラッシュしたりできます。

ここでは、トランザクションを開始し、各反復でそれをコミットし、毎回エンティティ マネージャーを作成/終了すると、多数のデータのパフォーマンスに影響します。

以下のようなコードになります。

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();

ここで、いずれかのオブジェクトが永続化/マージに失敗した場合、トランザクション全体をロールバックすることもできます。

于 2012-06-12T10:44:23.837 に答える