我有一个在Internet上找不到的问题。
我正在尝试使用ojdbc6连接到DB。我从jndi获取资源
<Resource name="jdbc/ds_conn" type="javax.sql.DataSource" maxTotal="10"
url="jdbc:oracle:thin:@someDB.com:1731/nameDB"
driverClassName="oracle.jdbc.OracleDriver"
connectionProperties="SetBigStringTryClob=true;
oracle.net.READ_TIMEOUT=5000;" password="pass" username="user"
maxWait="10000" maxIdle="300" maxActive="1000" auth="Container"/>
与方法
public OracleConnection getConnection() throws OracleDatabaseReaderConnectionException, NamingException {
Context initialContext = null;
try {
initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("java:comp/env/jdbc/ds_conn");
OracleConnection connection = (OracleConnection) dataSource.getConnection().unwrap(OracleConnection.class);
return connection;
} catch (NamingException | SQLException e) {
e.printStackTrace();
throw new OracleDatabaseReaderConnectionException(e.getMessage());
} finally {
if (initialContext != null) {
initialContext.close();
}
}
}
接下来我要执行查询
try (OracleConnection connection = getConnection();
OraclePreparedStatement preparedStatement = (OraclePreparedStatement) connection.prepareStatement(sqlQuery);
OracleResultSet resultSet = (OracleResultSet) preparedStatement.executeQuery()) {
//some actions
} catch (OracleDatabaseReaderConnectionException | SQLException | NamingException e) {
throw new OracleDatabaseReaderException(e.getMessage());
}
}
据我了解,连接数据库并执行查询是一种常见的操作。
但是连接不会关闭。正如您在我的jndi中看到的那样,我有参数maxTotal =“ 10”。因此,在10个查询池变满并且其他查询仅在池中等待一个位置之后。我不知道如何解决此问题并关闭连接。在将Connection转换为OracleConnection等时可能发生冲突吗?也许您的资源运作不好?
最佳答案
问题是您要关闭内部的OracleConnection
而不是外部的包装器。区别在于前者确实关闭了连接,而关闭包装器只会将连接返回到池中。
(OracleConnection) dataSource.getConnection().unwrap(OracleConnection.class);
在这里调用
unwrap()
会使池包装程序消失,并且您不能再在其上调用close
了。解决此问题的一种方法是仅在启动unwrap()
之后才调用try-with-resources
,如下所示:try (Connection connection = getConnection()) { // Now the pooled connection will be "closed"
OracleConnection oc = connection.unwrap(OracleConnection.class);
try(OraclePreparedStatement ps ...) ...
但这不是很漂亮,至少在很多地方都需要这样做。在这里绝对需要使用Oracle特定类而不是JDBC接口吗?