关闭

ProC血的教训之二!游标使用完关闭之后最好释放!

1834人阅读 评论(0) 收藏 举报

在经历上一个教训并解决问题之后,本以为可以高枕无忧了,结果又遇到一个问题,在多次拔插网线之后,程序运行到fetch cursor的时候就崩掉了,任何信息都没有提示。我确定是上下文的问题,但是怎么也改不好,我的程序没有用到多线程,而且reconnect之前也都关闭数据库连接了,为了确定使用全局上下文,我在每个函数开始的地方加了EXEC SQL CONTEXT USE DEFAULT这句,还是在EXEC SQL处崩溃!又花了我半天的时间,终于找到原因。

在最后时刻,我想,为什么这次出现问题的总是游标?而且总是在fetch的地方?为什么declare 游标没问题,open也没问题?我在fetch游标之前加了一句普通的SQL,发现是没问题的,这更加让我确定是游标的问题。可是开始游标是可以正常执行fetch的啊,我每次都declare-->open-->fetch-->close,对了,程序每次都declare,这不是重复声明吗?为什么之前没有问题,close对应的貌似是open,declare的时候或许是这样的,如果没有这个游标就创建,有的话就使用原来的,难道declare对应的还有一个反操作?我能想到的就是销毁或者就是RELEASE,于是网上一搜,还真有,是我基础不扎实,关键在下面这段话:


关于游标的释放

在一个连接中,若该连接引用记数为1,则关闭该连接也释放游标;如在同一个进程中打开连接,操作数据,关闭连接。

若连接记数大于1,如父进程打开连接,子进程共享该连接进行操作,则连接记数大于1,子进程不能做关闭连接操作。此时要释放一个游标,在关闭游标后,还必须做commit或rollback;此外,还要设置release_cursor选项为yes,设置方法是在proc命令行中增加release_cursor=yes,或在程序中编写:

EXEC ORACLE OPTION(RELEASE_CURSOR=YES);  

否则不能释放,最终会报-1000错:maximum open cursors exceeded。

我有点明白了,declare的游标也是与数据库连接或者上下文绑定的,如果没有释放的话,这个游标还是存在的,那么当程序连接换到另一个时,使用游标却还是在原来的那个连接上,所以可能会导致莫名奇妙的错误。于是我在游标close之后加了

EXEC ORACLE OPTION(RELEASE_CURSOR=YES),经过测试,没有再出现程序崩溃的问题。
因此,在程序可能会使用多个数据库连接的情况,游标使用完最好要释放。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    最新评论