4

私はGWTとHibernate、c3p0、およびMySQLを使用して、限られたオーディエンス(1日あたり最大50ユーザー)でWebアプリを作成しています。close()テスト中に、メソッドの使用に関係なく、Hibernateが各セッションとの接続を開いていたが、閉じていなかったことがわかりました。

私の現在の構成は次のとおりです。

hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=
hibernate.connection.username=
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.current_session_context_class=thread
hibernate.c3p0.min_size=1
hibernate.c3p0.max_size=1
hibernate.c3p0.timeout=10
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=10
hibernate.c3p0.unreturned_connection_timeout=1
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider

アプリケーションへの新しい接続ごとに、新しいプールが作成されます。たとえば、プールサイズを3に設定した場合、アプリケーションへの2つの接続は、アプリケーションが閉じられるまで6つの接続になります。

意図された動作は、各トランザクションの後に接続を単に閉じるか再利用することです。どうすればこれを達成できますか?

4

3 に答える 3

7

テスト中に、close()メソッドの使用に関係なく、Hibernateが各セッションとの接続を開いていたが、閉じていなかったことがわかりました。

接続プールを使用する場合、呼び出しConnection#close()は接続を物理的に閉じませんが、将来の再利用のためにプールに戻します。言い換えれば、接続は開いたままであり、それがプールを使用することの全体的なポイントです。


私は以下を呼び出します:AnnotationConfiguration()。buildSessionFactory()。getCurrentSession();

まあ、それが問題です。アプリケーションの存続期間中、 1回だけ作成する必要がありますが、何度も作成しSessionFactoryています(それぞれが独自のプールを作成しています)。特定のフレームワークを使用していない場合、これは通常、いくつかのユーティリティクラス(有名なクラス)で行われます。HibernateUtil

公式のHibernateチュートリアルには、そのようなクラスの非常に基本的な例があります。または、少しリッチなこれを参照してください。

于 2010-09-22T14:07:10.813 に答える
2

接続プールの概念はまさにそれです。開いている接続のプールがあり、トランザクションを実行する必要がある場合は、接続がすでに開かれています。このようにして、接続の開閉にかかる時間を大幅に節約できます。ただし、接続を使用していないときに接続を開いたままにしておくための代償を払ってください。

c3p0構成に関する詳細情報があります

更新どうやらOPはbuildSessionFactoryセッションごとに1回呼び出していたようです。これは、アプリケーションの存続期間ごとに1回呼び出す必要があります。

これは、HibernateのsessionFactoryを構築し、それを要求する人にセッションクラスを提供するユーティリティクラスです。これはDAOクラスのカンバーストーンです。

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;


public class HibernateUtil {

      private static final SessionFactory sessionFactory;

      static {
          try {
              // Create the SessionFactory from hibernate.cfg.xml
              sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
          } catch (Throwable ex) {
              // Make sure you log the exception, as it might be swallowed
              System.err.println("Initial SessionFactory creation failed." + ex);
              throw new ExceptionInInitializerError(ex);
          }
      }

      public static SessionFactory getSessionFactory() {
          return sessionFactory;
      }

      public static Session getCurrentSession() {
          return sessionFactory.getCurrentSession();
      }

}
于 2010-09-22T10:42:04.833 に答える
1

各トランザクションの後に接続を閉じたい場合は、接続プールを使用するのは良い考えではありません。それはまさに接続プールが避けたいものです...あなたはただC3POをオフにするべきです。Hibernateは接続を自分で処理します(各トランザクションで単純なJDBC接続として開いたり閉じたりします)

于 2010-09-22T12:47:52.197 に答える