我遇到了一个我在互联网上找不到的问题。
我正在尝试使用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());
}
}
据我所知,这是连接到db并执行查询的常用操作。
但连接没有关闭。正如你在我的jndi中看到的,我有param maxTotal =“10”。因此,在10个查询池变满后,其他查询只等待池中的某个位置。我不知道如何解决这个问题,并使连接关闭。也许我在连接到OracleConnection等方面存在冲突?也许你的资源不能很好地运作?
答案 0 :(得分:2)
问题是你正在关闭内部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接口?