spring - 如何在上下文卸载时关闭连接池?

标签 spring hibernate tomcat c3p0

在开发了几个与 spring、hibernate 和 c3p0 都具有类似设置的 webapps 作为连接池之后,我想调查一个我每次都注意到的问题: 连接池保持连接,直到您关闭 tomcat(或您的应用程序服务器)。

今天,我使用这四个依赖项创建了最基本的项目:

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>

应用程序上下文由两个 bean 组成 - 数据源和 session 工厂:

<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 建立的三个初始连接。

问题:当我告诉 tomcat 停止 web 应用程序时,它们仍然存在!

我创建了另一个 ServletContextListener,它只实现了 contextDestroyed 方法并以编程方式关闭了 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);
        }
    }
}

但真的是这样吗?是否没有我不知道的内置机制?

最佳答案

您是否尝试过指定销毁方法?

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

关于spring - 如何在上下文卸载时关闭连接池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532302/

相关文章:

java - Spring 版本变更导致 RESTful 功能中断

java - 使用@Autowired环境读取属性文件 spring java 空指针异常

Java Unirest 禁用证书

mysql - Hibernate 事件监听器未捕获事件

java - jhipster V5.8.2 中将initialValue 添加到SequenceGenerator

java - 错误无法检测 ServletContainerInitializers Tomcat 8

Tomcat 7.0.27更新后启动报错

java - @Value 注解不从属性文件中注入(inject)值

java - 如何将日期时间存储在本地时间中,以便可以通过 hibernate 明确检索?

成功登录复杂化后的 Tomcat JDBCRealm 重定向