Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如何在上下文卸载时关闭连接池?_Spring_Hibernate_Tomcat_C3p0 - Fatal编程技术网

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

Spring 如何在上下文卸载时关闭连接池?,spring,hibernate,tomcat,c3p0,Spring,Hibernate,Tomcat,C3p0,在开发了几个Web应用程序之后,它们都使用spring、hibernate和c3p0作为连接池进行了类似的设置,我想调查一个我每次都注意到的问题: Connectionpool将保持连接,直到您关闭tomcat(或您的应用程序服务器) 今天,我用以下四个依赖项创建了最基本的项目: org.springframework:spring-web org.springframework:spring-orm org.hibernate:hibernate-core c3p0:c3p0 (加上特定的J

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

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

org.springframework:spring-web
org.springframework:spring-orm
org.hibernate:hibernate-core
c3p0:c3p0
(加上特定的JDBC驱动程序)

My 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>

上下文配置位置
/WEB-INF/applicationContext.xml
org.springframework.web.context.ContextLoaderListener
应用程序上下文由两个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>

org.postgresql.Driver
jdbc:postgresql://localhost/mydb
usr
pwd
当我启动webapp并查看jconsole的MBean或检查我的DBMS是否存在打开的连接时,我注意到c3p0创建的三个初始连接

问题:当我告诉tomcat停止webapp时,它们仍然存在

我创建了另一个ServletContextListener,它只实现了contextDestroyed方法,并通过编程关闭sessionFactory(还取消了JDBC驱动程序的注册,这也不是自动完成的)。 代码是:

@覆盖
公共无效上下文已销毁(ServletContextEvent sce){
...
sessionFactory().close();
//取消注册sql驱动程序
枚举驱动程序=DriverManager.getDrivers();
while(drivers.hasMoreElements()){
Driver-Driver=drivers.nextElement();
试一试{
DriverManager.deregisterDriver(驱动程序);
log.info(“取消注册jdbc驱动程序:“+驱动程序”);
}捕获(SQLE异常){
log.error(“注销jdbc驱动程序时出错:“+driver,e”);
}
}
}

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

是否尝试指定销毁方法

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


没有什么比经验更宝贵了。。。成功了!谢谢(但是jdbc驱动程序注销怎么办?)驱动程序注销只是将它们从
DriverManager
的内部静态列表中删除。当连接池下次想要获取新资源时,它会向
DriverManager
请求该资源。但是,如果连接已经被获取并保留在池中,那么就没有什么可以阻止它继续工作。顺便说一句,这也会导致类加载器内存泄漏,因为连接池线程不允许类被销毁。若你们觉得并没有进一步的问题,请将问题标记为已解决。你们有并没有在上下文停止中看到过这种输出?--严重:web应用程序[/example]注册了JDBC驱动程序[org.postgresql.driver],但在web应用程序停止时未能注销它。为了防止内存泄漏,JDBC驱动程序已被强制注销。--我想知道为什么tomcat的家伙们在没有危害的情况下强制取消注册它。它实际上与未停止的线程有相同的危害——类加载器泄漏。每个类都持有对加载它的类加载器的引用,类加载器持有对它加载的所有类的引用。因此类加载器不能被GC'ed,所有的类也不能被GC'ed,你会从内存中得到permgen。以下是如何摆脱这个警告:好的,谢谢!正如您所看到的,我在上一个代码片段中已经有了这一点。
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">