Oracle的异常在系统开发中经常遇到 游标达到上限而报错
一、基本概念:
1. 游标是依附于statement 每一次statement的执行都会产生一个游标 如果具备良好的编码习惯 本异常是不会出现的 因为cursor在statement.close()后就会被释放了 所以主要的问题是statement的及时关闭 无论是在什么地方
2. Oracle数据库可以设置游标上限 open_cursor, 此上限是基于一个connection/session,如果一个connection的游标超限 异常就跑出来了
二、相关查询语句
(1)查看opened 游标:
select * from v$sesstat a,v$statname b where a.STATISTIC#=b.STATISTIC# and b.NAME='opened cursors current';
(2) 查看session:
select * from v$session where username is not null;
(3)配置增加cursor的上限
alter system set open_cursor 800, scope both;
三. 遇到的问题
描述:系统中有个业务比较复杂,首先建立一些临时表 然后伴随着增删查的操作 最后把connection放到session中缓存 期间执行的数据库语句有成百上千次 在增删改查的过程中 报出了这个错误
(1) .首先去检查是否有rs, statement没有close
(2). 配合查询游标sql看一下是哪些code导致游标不断增长而不释放
结果:最后发现是操作临时表的时候虽然执行了statement.close();但是其游标并没有被释放
自己写了个临时程序去印证了这一点 参见文章最后代码TestCursorOracle.java
为什么cursor不释放呢 我去找相关的资料 不过还是不知道为什么 大牛知道的话麻烦解释下 谢谢
四. 解决:
由于系统用的WAS 容器可以配置一些参数去管理数据库的连接 其中有个参数叫statement cache size 可以设置的小一些 个人理解 当statement达到一定数量的时候 容器回去关闭最久最少不用的 cursor就跟着释放了
然后增大数据库cursor的上限
另外tomcat的话可以参照poolPreparedStatements的变量
五. 总结:问题解决不完美 有点遗憾 不过时间有限 限记录下
注意:
1. statement、resultset、connect