java.sql.SQLException:-Ora-01000:超出最大打开游标

java.sql.SQLException:-Ora-01000:超出最大打开游标

我得到了一个Ora-01000 SQL异常。所以我对此有一些疑问。

  1. 最大打开游标与JDBC连接的数量完全相关,还是与我们为单个连接创建的语句和结果集对象有关?(我们正在使用连接池)
  2. 是否有一种方法来配置数据库中的语句/结果集对象的数量(比如连接)?
  3. 在单线程环境中使用实例变量语句/结果集对象而不是方法本地语句/结果集对象是明智的吗?
  4. 在循环中执行准备好的语句会导致这个问题吗?(当然,我可以使用sqlBatch)注意:一旦循环结束,pStmt就会关闭。

    { //method try starts  
      String sql = "INSERT into TblName (col1, col2) VALUES(?, ?)";
      pStmt = obj.getConnection().prepareStatement(sql);
      pStmt.setLong(1, subscriberID);
      for (String language : additionalLangs) {
        pStmt.setInt(2, Integer.parseInt(language));
        pStmt.execute();
      }} //method/try ends{ //finally starts
       pStmt.close()} //finally ends
  5. 如果在单个连接对象上多次调用con.createStatement()和con.presareStatement(SQL),会发生什么情况?

编辑1:6.使用弱/软参考陈述对象是否有助于防止渗漏?

编辑2:1.有没有办法,我能在我的项目中找到所有缺失的“语句”吗?我知道这不是记忆泄露。但是,我需要找到符合垃圾收集条件的语句引用(其中没有执行CLOSE()?有可用的工具吗?还是我必须手动分析?

请帮我理解一下。

若要在Oracle DB中查找用户名-Velu中打开的游标,请执行以下操作

转到Oralce机器并以sysdba的形式启动sqlplus。

[oracle@db01 ~]$ sqlplus / as sysdba

那就跑

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'
    AND USERNAME     = 'VELU';

如果可能的话,请在结尾读我的答案。


慕娘9325324
浏览 1114回答 3
3回答

饮歌长啸

我不想再多说几句话了。游标只涉及语句objecct;它既不是结果集,也不是连接对象。但是,我们仍然必须关闭结果集以释放一些Oracle内存。不过,如果不关闭结果集,则不会将其计算为游标。关闭语句对象也会自动关闭结果集对象。将为所有SELECT/INSERT/UPDATE/DELETE语句创建游标。每个Oracle DB实例都可以使用oracle SID标识;类似地,Oracle DB可以使用连接SID标识每个连接。两个希德都不一样。因此,Oracle会话只不过是一个JDBC(TCP)连接;它只不过是一个SID。如果我们将最大游标设置为500,那么它只适用于一个JDBC会话/Connection/SID。因此,我们可以使用它各自的NO游标(语句)进行许多JDBC连接。JVM终止后,所有连接/游标都将关闭,否则JDBCConnection将关闭该连接的游标。以塞斯迪巴的身份。在Putty(Oracle登录)中:  [oracle@db01 ~]$ sqlplus / as sysdba在SqlPlus中:用户名:sys as sysdba将Session_Cached_游标值设置为0,这样就不会有关闭游标了。 alter session set session_cached_cursors=0  select * from V$PARAMETER where name='session_cached_cursors'选择DB中每个连接的现有OPEN_游标值集 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;下面是查找带有打开游标值的SID/Connections列表的查询。 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' AND username = 'SCHEMA_NAME_IN_CAPS'使用下面的查询标识打开游标中的SQL SELECT oc.sql_text, s.sid   FROM v$open_cursor oc, v$session s  WHERE OC.sid = S.sid  AND s.sid=1604  AND OC.USER_NAME ='SCHEMA_NAME_IN_CAPS'现在调试代码并享受!)

湖上湖

请按以下方式更正您的代码:try{ //method try starts     String sql = "INSERT into TblName (col1, col2) VALUES(?, ?)";   pStmt = obj.getConnection().prepareStatement(sql);   pStmt.setLong(1, subscriberID);   for (String language : additionalLangs) {     pStmt.setInt(2, Integer.parseInt(language));     pStmt.execute();   }} //method/try endsfinally{ //finally starts    pStmt.close()}你确定你真的要关闭你的pStatement,连接和结果吗?要分析打开的对象,可以执行委托模式,它将代码包装在状态对象、连接对象和结果对象周围。因此,您将看到,如果一个对象将成功关闭。例如:pStmt=obj。getConnection().preareStatement(SQL);    class obj{      public Connection getConnection(){     return new ConnectionDelegator(...here create your connection object and put it into ...);     } }class ConnectionDelegator implements Connection{     Connection delegates;     public ConnectionDelegator(Connection con){        this.delegates = con;     }     public Statement prepareStatement(String sql){         return delegates.prepareStatement(sql);     }     public void close(){         try{            delegates.close();         }finally{            log.debug(delegates.toString() + " was closed");         }     }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java