关于V$OPEN_CURSOR

在之前的一次讨论中,有同行指出V$OPEN_CURSOR中列出的不是OPEN CURSOR而是SESSION CACHED CURSOR,原因是在一次ORA-01000(maximum open cursors exceeded)事故中他没有从V$OPEN_CURSOR中找到大量的打开游标。 对于这个问题,我们可以利用JAVA程序做一个演示来说明,以下为JAVA代码:
package javaapplication2;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.jdbc.*;
import java.sql.*;

public class Main {

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        }catch(Exception e ){}
   Connection cnn1=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:G11R2", "maclean", "maclean");

  // Connection m[]=new Connection[2000];
   Connection myconn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:G11R2", "maclean", "maclean");

    Statement stat1=myconn.createStatement();
   ResultSet rst1=stat1.executeQuery("select * from v$version");
   while(rst1.next())
   {
       System.out.println(rst1.getString(1));
   }
   rst1=stat1.executeQuery("select distinct sid from v$mystat");

   while (rst1.next()){
   System.out.println("MY SID IS "+rst1.getString(1));
        }

   PreparedStatement s[]=new PreparedStatement[2000];
   PreparedStatement p;
   //ResultSet r[]=new ResultSet[2000];
   int i=0;
   while(i<2000){
    //  m[i]=DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.121:1521:G10R2", "maclean", "maclean");
      //s[i]=m[i].createStatement();
      //m[i].setAutoCommit(false);
      //s[i].execute("insert into testjava values(1)");
       p=myconn.prepareStatement("select /* FIND_ME_OPPO */ * from dual");
       p.execute();

            try {
                Thread.sleep(200);
            } catch (InterruptedException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }

      i++;
      System.out.println(i+" cursor is ok !");
   }
   }
}
以上JAVA代码会打个一个数据库会话,并在循环中不断以prepareStatement对象执行SQL语句,且我们不使用close()方法关闭prepareStatement所打开的游标,实际上这是很多JDBC应用产生ORA-01000问题的主要原因,开发人员在使用prepareStatement时不知道要使用close()方法以回收OPEN CURSOR资源。 注意这里在使用JDBC API时的表现(可能是目前最流行应用形式)和PL/SQL中的游标是存在区别的,在PL/SQL使用close cursor语句并不会真正意义上关闭游标。出于性能的考量,PL/SQL中的游标将被缓存以备将来使用,同时Oracle会维护一张cursor的LRU列表,但如果当本会话的游标数量即将达到open_cursors参数所定义的上限数量时,老的游标将被真正意义上close,以便open后来者。
The following is a technical explanation provided by Oracle Development:  The server caches cursors opened by the PL/SQL engine.
分享至
一键收藏,随时查看,分享好友!
0人
了这篇文章
类别:未分类┆阅读( 0)┆评论( 0) ┆ 返回博主首页┆ 返回博客首页
上一篇 Script:Speed Up Large Index Create or Rebuild 下一篇 Buffer Lock Mode and Compatibilities

职位推荐

  • Oracle数据开发工程师
  • 前台接待
  • 数据库开发工程师/BI工程师
  • 数据库管理员
  • DBA
  • 程序员
  • ETL开发工程师(上海)
  • 数据库管理工程师
  • PHP开发工程师
  • 售前顾问(数据库方向)

文章评论

 
 

发表评论            

昵  称:
登录  快速注册
验证码:

点击图片可刷新验证码请点击后输入验证码博客过2级,无需填写验证码

内  容:

同时赞一个

每日博报 精彩不止一点关闭

你可能感兴趣的:(cache,Lock,Cursor,library,open,sharing)