8

spring、hibernate、および c3p0 を接続プールとして使用する同様のセットアップを持ついくつかの Web アプリケーションを開発した後、私が毎回気づいた問題を調査したいと思いました。接続プールは、Tomcat (またはアプリケーション サーバー) をシャットダウンするまで接続を保持します。

今日、次の 4 つの依存関係を使用して、最も基本的なプロジェクトを作成します。

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

(および特定の JDBC ドライバー)。

私の 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>

webapp を開始し、jconsole の MBean を調べるか、DBMS で開いている接続を確認すると、c3p0 によって行われた 3 つの初期接続に気付きました。

問題: tomcat に webapp を停止するように指示しても、まだ残っています!

contextDestroyed メソッドのみが実装され、プログラムで sessionFactory をシャットダウンする別の ServletContextListener を作成しました (また、自動的に行われない 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);
        }
    }
}

しかし、それは本当にそれですか?私が認識していない組み込みのメカニズムはありませんか?

4

1 に答える 1

14

destroy-methodを指定しようとしましたか?

<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
于 2012-11-23T15:58:35.647 に答える