2012-11-23 10 views
5

接続プールとしてspring、hibernate、c3p0と同様の設定をしたいくつかのWebアプリケーションを開発した後、私は気づいた問題を調査したかったのです。 Tomcat(またはアプリケーションサーバー)を終了するまでConnectionpoolは接続を維持します。コンテキストアンロード時に接続プールをシャットダウンする方法はありますか?

org.springframework:spring-web 
org.springframework:spring-orm 
org.hibernate:hibernate-core 
c3p0:c3p0 

(プラス特定のJDBCドライバ):

今日、私は、これらの4つの依存関係を持つ私ができる最も基本的なプロジェクトを作成します。

私のweb.xmlは、アプリケーションコンテキストを設定するContextLoaderListenerのみを作成します。

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     /WEB-INF/applicationContext.xml 
    </param-value> 
</context-param> 

<listener> 
    <listener-class> 
     org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 

アプリケーションコンテキストは、2つのBeanで構成 - データソースとセッション工場:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
    <property name="driverClass"> 
     <value>org.postgresql.Driver</value> 
    </property> 
    <property name="jdbcUrl"> 
     <value>jdbc:postgresql://localhost/mydb</value> 
    </property> 
    <property name="user"> 
     <value>usr</value> 
    </property> 
    <property name="password"> 
     <value>pwd</value> 
    </property> 
</bean> 

は、私がWebアプリケーションのいずれかのjconsoleのMBeanに見えるか、私は3つの初期接続に気づくオープン接続のための私のDBMSをチェックを開始c3p0によって作られた。

問題:ウェブアプリケーションを停止するようにtomcatに指示すると、それらはまだ残っています!

私はcontextDestroyedメソッドしか実装されていない別のServletContextListenerを作成し、プログラムによってsessionFactoryをシャットダウンします(また自動的に行われないJDBCドライバも登録解除されます)。 コード:

@Override 
public void contextDestroyed(ServletContextEvent sce) { 

    ... 
    sessionFactory().close(); 

    // deregister sql driver(s) 
    Enumeration<Driver> drivers = DriverManager.getDrivers(); 
    while (drivers.hasMoreElements()) { 
     Driver driver = drivers.nextElement(); 
     try { 
      DriverManager.deregisterDriver(driver); 
      log.info("deregistering jdbc driver: " + driver); 
     } catch (SQLException e) { 
      log.error("error deregistering jdbc driver: " + driver, e); 
     } 
    } 
} 

これは本当ですか?私が気づいていない組み込みのメカニズムはありませんか?

答えて

12

破壊メソッドを指定しようとしましたか?

<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
+0

経験と同じくらい貴重なものはありません...それは機能しました!ありがとうございます(ただし、jdbcドライバの登録解除はどうですか?) – realsim

+1

ドライバの登録を抹消すると、 'DriverManager'の内部静的リストから削除されます。次回に接続プールが新しいリソースを取得したいときは、それを 'DriverManager'に問い合わせます。しかし、接続がすでに獲得されてプールに残っていると、それが動作し続けるのを妨げるものは何もありません。ところで、接続プールスレッドはクラスを破棄しないため、クラスローダーのメモリリークも発生します。さらなる質問がないと思われる場合は、問題を解決済みとマークしてください。 –

+0

@realsim:この回答を受け入れることを忘れないでください! –

関連する問題