Java 應用若未正確關閉 Statement/ResultSet,易導致 ORA-01000: maximum open cursors exceeded。透過動態效能視圖 V$MYSTAT、V$OPEN_CURSOR 可快速定位洩漏的 SQL 文本。
SELECT a.value, a.sid
FROM v$mystat a, v$statname b
WHERE a.statistic# = b.statistic#
AND b.name = 'opened cursors current';
SELECT sql_text
FROM V$OPEN_CURSOR
WHERE sid = :sid;
rs.close()、stmt.close()。try {
String qry = "SELECT a.value, b.name, a.sid FROM v$mystat a, v$statname b " +
"WHERE a.statistic# = b.statistic# AND b.name = 'opened cursors current'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(qry);
if (rs.next()) {
long openCursors = rs.getLong(1);
int sid = rs.getInt(3);
if (openCursors > 1) { // 正常應為 1 (僅此查詢)
// 查詢具體 SQL
Statement stmt2 = conn.createStatement();
ResultSet rs2 = stmt2.executeQuery(
"SELECT sql_text FROM V$OPEN_CURSOR WHERE sid = " + sid);
while (rs2.next()) {
System.out.println("Leaked SQL: " + rs2.getString(1));
}
rs2.close(); stmt2.close();
throw new Exception("Cursor leak detected, open=" + openCursors);
}
}
rs.close(); stmt.close();
} catch (Exception e) { e.printStackTrace(); }
Connection, Statement, ResultSet) 必須在 finally 區塊或 try-with-resources (Java 7+) 中關閉。maxOpenPreparedStatements 限制預編譯語句快取數量。V$SYSSTAT 的 opened cursors current 總量,設定告警閾值。