ORACLE 打开游标过多

2023年 2月 22日 67点热度 0人点赞

1. 原因分析

Java代码在执行conn.createStatement()conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor,当PreparedStatement或statement执行操作之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statement或PreparedStatement关闭。

尤其是在循环中,因为游标一直在不停的打开,而且没有关闭。

综上所述:上面的代码在pstmt.execute();之后执行pstmt.close();方法即可。

 

2. 语句

2.1. 查看系统中已打开游标的最大数和允许打开有表达最大数

SELECT MAX(a.value) AS highest_open_cur,
       p.value AS max_open_cur
FROM v$sesstat a,
     v$statname b,
     v$parameter p
WHERE a.statistic# = b.statistic#
  AND b.name = 'opened cursors current'
  AND p.name = 'open_cursors'
GROUP BY p.value;

 

2.2. 查看系统中打开游标数的SID

 

SELECT a.value,
       s.username,
       s.sid,
       s.serial#
FROM v$sesstat a,
     v$statname b,
     v$session s
WHERE a.statistic# = b.statistic#
  AND s.sid = a.sid
  AND b.name = 'opened cursors current'
ORDER BY 1 DESC;

 

2.3. 通过SID去查找未关闭PreparedStatement的SQL

SELECT oc.sid,
       oc.hash_value,
       oc.sql_text,
       COUNT(*) how_many
FROM v$open_cursor oc
GROUP BY sid,
         hash_value,
         sql_text
ORDER BY 4 DESC;

 

 

2.4. 每一次createPreparedStatement()之后记得关闭

 

PreparedStatement ps = null;
ResultSet rs = null;
try {
    ps = tsn.createPreparedStatement(sql, 1);
    rs = ps.executeQuery();
} catch (Exception e) {
    throw OAException.wrapperException(e);
} finally {
    try {
        if (rs != null) {
            rs.close();
        }
        if (ps != null) {
            ps.close();
        }
    } catch (SQLException ex) {
        throw new RuntimeException(ex);
    }
}

 

 

 

rainbow

这个人很懒,什么都没留下

文章评论