Java Oracle 连接池 - 关闭连接异常
这篇文章的目的不是提出问题,而是确认我正在正确地做事。我看过很多类似的帖子,但我不确定我是否完全理解其中所说的一切。
问题是,在一段时间后,我在尝试建立与 Oracle 数据库的连接时遇到异常。 (我使用的是 Tomcat 6.0 和 Spring)
以前我有以下配置:
private PoolDataSource poolDataSource = null;
public MainDAOImpl(String url, String username, String password)
throws Exception
{
poolDataSource = PoolDataSourceFactory.getPoolDataSource();
try
{
poolDataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
poolDataSource.setURL(url);
poolDataSource.setUser(username);
poolDataSource.setPassword(password);
}
catch( SQLException e )
{
...
}
}
public List<Object> getValues(String query)
{
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
connection = poolDataSource.getConnection();
preparedStatement = connection.prepareStatement(query);
...
}
catch( SQLException e )
{
...
}
finally
{
//close connections
}
}
但是,有时 preparedStatement = connection.prepareStatement(query);
会抛出带有“Closed Exception”消息的 SQLException。
需要注意的是,每次服务器重新启动时,MainDAOImpl 的构造函数只会被调用一次(它是通过 Spring 注入的依赖项)。
我最近将我的设置更改为:
private DataSource dataSource = null;
public MainDAOImpl()
throws Exception
{
try
{
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/myOracleConn");
}
catch( NamingException e )
{
...
}
}
将 poolDataSource.getConnection()
更改为 dataSource.getConnection()
。
我还在 Tomcat 中的上下文中添加了以下资源:
<Resource name="jdbc/myOracleConn" auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="<myURL>"
username="<myUsername>" password="<myPassword>"
maxActive="20" maxIdle="10" maxWaith="-1" />
这基本上遵循 http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html 逐字逐句。
一切似乎都正常。我的问题是,这些更改会解决我的关闭连接问题还是我需要做一些不同的事情?
谢谢,
北京
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,如果你使用 Spring 进行依赖注入,我建议你也使用 DI 将 DAO 的依赖注入其中。
换句话说,您的 DAO 应该注入一个 DataSource,而不是 DAO 实现知道 1) 要构造什么类型的 DataSource 或 2) 如何以及在何处在 JNDI 中查找它。春天 可以为您处理 JNDI 查找。
我还建议使用 Spring 的 JdbcTemplate,因为它为您自己的原始 JDBC 调用提供了一个很好的包装器。
最后,您收到的实际异常可能只是因为数据库服务器正在关闭长时间打开的连接。不确定您使用的是哪种连接池实现,但在 commons-dbcp 中有 “validationQuery”的选项,池将在返回连接之前执行该选项以验证连接是否仍然有效。我确信大多数其他池都提供类似的功能,我在这里推荐 - 这样您的 DAO 就永远不会从池中接收过时的连接。
First of all, if you are using Spring for dependency injection, I would recommend that you also use DI to inject the DAO's dependencies into it.
In other words, your DAO should have a DataSource injected into it, rather than the DAO implementation knowing either 1) what type of DataSource to construct or 2) how and where to look it up in JNDI. Spring can handle JNDI lookups for you.
I'd also recommend using Spring's JdbcTemplate, as it makes for a great wrapper over raw JDBC calls yourself.
Finally, the actual exception you are getting may just be because the database server is closing long-open connections. Not sure which connection pool implementation you are using, but in commons-dbcp there is an option for a "validationQuery" which the pool will execute before returning a connection to verify the connection is still valid. I'm sure most other pools supply similar features, which I would recommend here - this way your DAO is never receiving stale connections from the pool.