Oracle游标的最大数异常汇总:
1.检查数据库中的 OPEN_CURSORS 参数值
a. 文件定义位置:
init.ora 中的初始化参数 OPEN_CURSORS 指定一个会话一次最多可以拥有的游标数,缺省值为 50。
b.查询方式:
show parameter open_cursors;
c. 使用小结:
将 OPEN_CURSORS 的值设置得足够大,以避免应用程序用尽所有打开的游标。
应用程序不同,该值也不同。
即设置的值高于实际需要的值,也不会增加系统开销。
2.获取打开的游标数
select o.sid, osuser, machine, count(*) num_curs
from v$open_cursor o, v$session s
where user_name = 'SCOTT' and o.sid=s.sid
group by o.sid, osuser, machine
order by num_curs desc;
from v$open_cursor o, v$session s
where user_name = 'SCOTT' and o.sid=s.sid
group by o.sid, osuser, machine
order by num_curs desc;
a.v$open_cursor 可以跟踪会话中 PARSED 和 NOT CLOSED 的动态游标
b.它不会跟踪未经分析(但已打开)的动态游标
3.获取为游标执行的 SQL
select q.sql_text
from v$open_cursor o, v$sql q
where q.hash_value=o.hash_value and o.sid = 217;
from v$open_cursor o, v$sql q
where q.hash_value=o.hash_value and o.sid = 217;
a.o.sid来自于2中查找到的id号
4.Java代码的调用:
4.Java代码的调用:
原因:
Java 代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。
解决方法:
写Java代码的时候,createStatement和prepareStatement都应该要放在循环外面,而且使用了这些Statment后,及时关闭。最好是在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statement 或PreparedStatement关闭。
5.连接池的应用
原因:
如果你不使用连接池,那么就没有什么问题,一旦Connection关闭,数据库物理连接就被释放,所有相关Java资源也可以被GC回收了。
但是如果你使用连接池,那么请注意,Connection关闭并不是物理关闭,只是归还连接池,所以PreparedStatement和 ResultSet都被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行,往往就会报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。
但是如果你使用连接池,那么请注意,Connection关闭并不是物理关闭,只是归还连接池,所以PreparedStatement和 ResultSet都被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行,往往就会报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。
解决:
在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将 Statement或PreparedStatement关闭。