为什么OracleConnection没有返回池中?

时间:2018-04-06 09:35:03

标签: java database oracle connection ojdbc

我遇到了一个我在互联网上找不到的问题。

我正在尝试使用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等方面存在冲突?也许你的资源不能很好地运作?

1 个答案:

答案 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接口?