3

MYSQLデータベースとSwingアプリケーションフレームワークおよびjavax.persistenceを使用して、かなり大きなCRUDアプリケーションを開発しました。私の質問は、javax.persistence.Entitymanagerを指定して、トランザクションをどのように最適に管理する必要があるかということです。現在、Applicationクラスによって保持されているエンティティマネージャーのインスタンスが1つあります。それはすべての要求ページに渡され、次にそれを使用してエンティティを永続化およびマージします。アプリケーションの起動時にトランザクションを開始し、変更が加えられるたびにコミット(および再起動)します。これは正しいです?または、コンポーネント/ページごとに個別のエンティティマネージャーを保持する必要がありますか?いつコミットする必要がありますか?最近、次のタイプの例外が発生し始めたため、これらすべての質問が発生しました。java.sql.SQLException:ロック待機タイムアウトを超えました。トランザクションを再開してみてくださいエラーコード:

あなたが私に与えることができるどんな助けにも前もって感謝します!

4

1 に答える 1

4

アプリケーションの起動時にトランザクションを開始することは、最善の方法ではありません。それぞれのトランザクションがデータベースをロックするため、トランザクションはできるだけ短くする必要があります。つまり、トランザクションが開始されるたびに、他のスレッドがデータベースに書き込むことはできません。あなたのやり方は正反対です: あなたのデータベースは、短期間だけロックされているわけではありません。それが、発生しているエラーの原因である可能性があります。

一般に、トランザクションを管理するための推奨される方法は次のとおりです。

EntityManager em = EMF.getEM();
    em.getTransaction().begin();
    // your persist, merge code goes here
    em.getTransaction().commit();
    em.close();

EMF クラスは次のとおりです。

public class EMF {
    private static EntityManagerFactory emf;
    static {
        emf = Persistence.createEntityManagerFactory("MyEMF");
    }
    public static EntityManager getEM(){
        return emf.createEntityManager();
    }
}

このようにして、トランザクションは、永続化コードが実行されている間だけデータベースをロックします。クラス EMF を使用すると、エンティティ マネージャ ファクトリは 1 回だけ作成されることに注意してください。作成には計算コストがかかるため、これは良いことです。ただし、一度エンティティ マネージャのインスタンスを作成すると、非常にコストがかかりません。この短いチュートリアルでは、かなりよく説明されています。

于 2011-09-07T19:22:00.927 に答える