5

DAO レイヤーには 19 のメソッドがあり、それぞれが次のバリエーションです。

public TicketProp saveTicketProp(TicketProp prop) {
    EntityManager em = this.emf.createEntityManager();
    try {
        em.getTransaction().begin();
        prop = (TicketProp) em.merge(prop);
        em.getTransaction().commit();
        return prop;
    } finally {
        em.close();
    }
}

意味: 各メソッドで、独自のトランザクションを処理し、finally ブロックで閉じます。Jersey アプリをテストしているので、JUnit テストは JerseyTest を拡張します。各テスト メソッドは、Grizzly コンテナーをインスタンス化し、テストを実行してから、コンテナーをシャットダウンします。EntityManagerFactory は、Spring によって注入されます。JPA over Hibernate を使用しています。

MySQL テスト DB への接続を監視していますが、接続は常に高くなっています。1 つのテストだけで、MySQL の "Max_used_connections" 変数を 38 まで実行します。楽しみのために、すべての em.close() 呼び出しをコメントアウトしましたが、テストではまだ 38 の接続を使用しています。

私はHibernateの組み込みの接続プールを使用しています(製品用ではありません、私は知っています)。私はまだある種のインテリジェントなプーリングを期待していました。

EntityManager の処理が間違っていますか? 他にどのように接続を閉じることができますか?

4

2 に答える 2

5

テストcloseEntityManagerFactory 最後に. の javadoc からEntityManagerFactory#close():

void javax.persistence.EntityManagerFactory.close()

ファクトリを閉じて、保持しているすべてのリソースを解放します。ファクトリ インスタンスが閉じられた後、呼び出されたすべてのメソッドは、false を返す をIllegalStateException除いて、 をスローします。isOpenが閉じられると、EntityManagerFactoryそのすべてのエンティティ マネージャは閉じられた状態にあると見なされます。

finally補足として、句内の EM を閉じる前に、実際にトランザクションをロールバックする必要があります。

public TicketProp saveTicketProp(TicketProp prop) {
    EntityManager em = this.emf.createEntityManager();
    try {
        em.getTransaction().begin();
        prop = (TicketProp) em.merge(prop);
        em.getTransaction().commit();
        return prop;
    } finally {
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }
}
于 2010-07-27T23:22:52.943 に答える
2

EntityManager.close()基礎となる接続を常に物理的に閉じるのはなぜだと思いますか? それは接続プール次第です(おそらくそれを構成し、同時に開く接続の最大数を設定する必要があります)。

于 2010-07-27T21:45:36.450 に答える