注意:我们重用单个连接。
************************************************
public Connection connection() {
try {
if ((connection == null) || (connection.isClosed()))
{
if (connection!=null)
log.severe("Connection was closed !");
connection = DriverManager.getConnection(jdbcURL, username, password);
}
} catch (SQLException e) {
log.severe("can't connect: " + e.getMessage());
}
return connection;
}
**************************************************
public IngisObject[] select(String query, String idColumnName, String[] columns) {
Connection con = connection();
Vector<IngisObject> objects = new Vector<IngisObject>();
try {
Statement stmt = con.createStatement();
String sql = query;
ResultSet rs =stmt.executeQuery(sql);//oracle increases cursors count here
while(rs.next()) {
IngisObject o = new IngisObject("New Result");
o.setIdColumnName(idColumnName);
o.setDatabase(this);
for(String column: columns)
o.attrs().put(column, rs.getObject(column));
objects.add(o);
}
rs.close();// oracle don't decrease cursor count here, while it's expected
stmt.close();
}
catch (SQLException ex) {
System.out.println(query);
ex.printStackTrace();
}
原文由 Vladimir 发布,翻译遵循 CC BY-SA 4.0 许可协议
init.ora 参数
open_cursors
定义一个会话可以同时拥有的最大打开游标。它的默认值为 50。如果应用程序超过此数字,则会引发错误“ORA-01000:超出最大打开游标数”。因此,当不再需要 JDBC 资源时必须关闭它们,特别是 java.sql.ResultSet 和 java.sql.Statement。如果它们没有关闭,应用程序就会发生资源泄漏。
在重用 Connection 对象的情况下,您必须意识到,只要连接存在 且 事务尚未结束,打开的 oracle 游标就会保持打开状态并处于使用状态。当应用程序提交时,打开的游标被释放。
因此,作为应用程序设计者,您需要粗略估计最复杂事务所需的打开游标。
困难在于 oracle 的内部参数视图(v\(open_cursor、v\)sesstat 等)无法显示打开的游标(可重用)和打开的游标(仍然被阻止(不可重用!))之间的区别未关闭的 ResulSet 或 Statement。如果您关闭 finally 块中的所有 Statement 和 ResultSet 对象,您的应用程序就完全没问题了。
调整 init.ora 参数是这样的(我们的应用程序最多需要 800 个游标)