我的程序中出现 MaxOpenPreparedStatement 异常。我可以使用 getNumActive()/getNumIdle() 函数监控 GenericObjectPool 中的对象数量。如何从 org.apache.commons.dbcp.BasicDataSource 对象获取连接和准备好的语句池?谢谢
3 回答
我不确定实际问题的答案,但打开的preparedstatements 的最大允许数量通常非常高。所以我强烈怀疑导致你问这个问题的技术问题是 JDBC 代码没有finally
按照以下 JDBC 习惯正确关闭块中所有打开的语句:
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
// ...
try {
connection = database.getConnection();
preparedStatement = connection.prepareStatement(SQL_STRING);
resultSet = preparedStatement.executeQuery();
// ...
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (preparedStatement != null) try { preparedStatement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
You might be able to get a hold of the DBCP internals by subclassing BasicDataSource, then overriding createPoolableConnectionFactory and replacing the statement pool factory with one you create yourself (and thus are able to track).
As with the other answers here, this would seem to indicate prepared statements are being left open - in which case you'll have the same problem even if you turn prepared statement pooling off (or stop using a connection pool at all), which might make the original problem a lot easier to debug.
DBCP 的 BasicDataSource 公开了配置数据源的maxOpenPreparedStatements值。
此异常的存在似乎表明您打开了太多语句而不是关闭它们:
由于一个连接通常一次只使用一两个语句,这主要用于帮助检测资源泄漏。