【发布时间】:2014-08-06 02:55:37
【问题描述】:
我有一个使用 Spring 在 Tomcat 7 下运行的 Web 应用程序,并使用 c3po 作为连接池管理器。我也用过dbcp,结果是一样的。
我启动了一个长时间运行的单线程进程,该进程在各种dao 中使用jdbcTemplate.update() 等进行大量数据库调用。由于这些更新中的每一个都简单且独立,因此没有使用事务管理器。
由于某种原因,我的连接用完了。似乎正在发生的事情是每个dao 都保持自己的连接,而不是将其返回到池中。
这是正常行为吗?我原以为连接会绑定到 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
}
所有道的继承自...
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;
}
【问题讨论】:
-
要发布连接等,您需要一个事务管理器,即使您的更新很简单,您也确实应该管理事务。应该是事务性的不是数据库层,而是应该驱动事务的服务层。
-
@M.Deinum 你需要一个事务管理器 - 你的评论对于 OP 的问题没有意义。如果连接未释放(即返回池),则问题一定出在代码中。拥有 TX 管理器是针对不同主题的建议。 JdbcTemplate 不需要活动事务才能正常工作。
-
您应该使用 TX 管理,但没有它不会导致您的问题。顺便提一句。您是在代码中手动调用 docs.oracle.com/javase/7/docs/api/javax/sql/… 吗?
-
请添加一些代码和配置。
-
所有 dao 都扩展了一个抽象类,该抽象类扩展了 JdbcDaoSupport。作为例外,你的意思是如果我没有为池提供足够的连接,我最终会得到错误吗?如果是这样,它最终会锁定在其中一个 dao 中,直到达到等待超时,此时它会引发异常(如果重要,我可以获取详细信息)
标签: java spring connection-pooling