我有一个在 Tomcat 7 下运行的 Web 应用程序,使用 Spring 和 c3po
作为连接池管理器。我也使用了 dbcp 并得到了相同的结果。
我启动了一个长时间运行的单线程进程,该进程在各种dao
中使用jdbcTemplate.update()
等进行大量数据库调用。由于每个更新都是简单且独立的,因此不使用事务管理器。
由于某种原因,我的连接耗尽了。似乎正在发生的事情是每个 dao
都保留着自己的连接,并且不会将其返回到池中。
这是正常行为吗?我原以为连接会绑定(bind)到 jdbcTemplate.update()
并在完成后立即释放。
...
在上下文文件中...
<bean id="enquiryDataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${enquiry.drivername}"/>
<property name="url" value="${enquiry.jdbc}"/>
<property name="username" value="${enquiry.username}"/>
<property name="password" value="${enquiry.password}"/>
<property name="maxWait" value="30000"/>
<property name="maxActive" value="50"/>
</bean>
在典型的 dao 构造函数中...
@Autowired
public XXXCountryDao(@Qualifier("enquiryDataSource") DataSource dataSource,
@Qualifier("sqlUpdaterFactoryImpl") SqlUpdaterFactory sqlUpdaterFactory, @Qualifier("sqlFormatterFactoryImpl") SqlFormatterFactory sqlFormatterFactory) {
super("Country", dataSource, sqlUpdaterFactory, sqlFormatterFactory);
// ...other constructor stuff
}
所有 dao 都继承自...
public abstract class AbstractFileProcessorDao<ImportRecType, QueryRecType> extends JdbcDaoSupport {
// ...
}
在典型的 dao 方法中...
protected boolean runUpdateToSqlDatabase(Map<String, Object> values, Map<String, Object> whereValues) {
if (values.isEmpty())
return true;
String sql = updateUpdaterServer.getSql(values, whereValues);
if (logger.isDebugEnabled())
logger.debug("Server SQL -> " + sql);
getJdbcTemplate().update(sql);
return false;
}
最佳答案
请检查您的应用程序是否存在对 DataSource#getConnection
的“恶意”调用(您可以使用 IDE 搜索方法引用)。连接泄漏通常是由于获取连接后从未通过 Connection#close
关闭而引起的.
使用 Spring 的 JdbcTemplate
时,所有 JDBC 资源处理(打开/关闭连接、语句、结果集)都是自动完成的。但对于遗留代码,你永远不知道。
关于java - C3PO 连接池 - 连接未释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24241045/