Java Oracle连接池 - 关闭连接异常
这篇文章的目的不是为了一个问题,而是为了确认我正确地做事。我见过很多类似的帖子,但我不确定自己完全理解了所说的一切。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);
抛出一个SQLException与 “封闭异常” 的消息。
重要的是要注意,每个服务器重新启动(它通过Spring注入的依赖项)MainDAOImpl的构造函数只被调用一次。
我最近改变了我的设置,像这样:
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字对字。
一切似乎都在工作。我的问题是,这些更改是否会解决我的关闭连接问题,还是存在与我需要做的不同的事情?
感谢,
B.J.
首先,如果你正在使用Spring依赖注入,我建议你也可以使用DI注入DAO的依赖性进去。
换句话说,你的DAO应该有一个注入到其中的数据源,而不是DAO实现要么知道1)要构造什么类型的数据源,要么2)在JNDI中查找它的方式和位置。春季can handle JNDI lookups为您服务。
我还建议使用Spring的JdbcTemplate,因为它可以让您自己对原始JDBC调用进行很好的封装。
最后,您得到的实际异常可能只是因为数据库服务器正在关闭长时间打开的连接。不知道您正在使用哪个连接池实施,但在commons-dbcp中有an option for a "validationQuery"池将在返回连接之前执行以验证连接是否仍然有效。我相信大多数其他池提供类似的功能,我会在这里推荐 - 这样,您的DAO永远不会从池中接收过时的连接。