在开发了几个与spring,hibernate和c3p0类似设置的webapps作为连接池之后,我想研究一下我每次都注意到的问题: Connectionpool保持连接,直到您关闭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组成 - 数据源和会话工厂:
<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停止webapp时,它们仍然存在!
我创建了另一个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);
}
}
}
但是真的吗?是否没有我不知道的内置机制?
答案 0 :(得分:13)
您是否尝试过指定destroy-method?
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">