为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕娘9325324 2019-07-06 15:11:27
java.sql.SQLException:-Ora-01000:超出最大打开游标我得到了一个Ora-01000 SQL异常。所以我对此有一些疑问。最大打开游标与JDBC连接的数量完全相关,还是与我们为单个连接创建的语句和结果集对象有关?(我们正在使用连接池)是否有一种方法来配置数据库中的语句/结果集对象的数量(比如连接)?在单线程环境中使用实例变量语句/结果集对象而不是方法本地语句/结果集对象是明智的吗?在循环中执行准备好的语句会导致这个问题吗?(当然,我可以使用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如果在单个连接对象上多次调用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';如果可能的话,请在结尾读我的答案。
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

我不想再多说几句话了。

  1. 游标只涉及语句objecct;它既不是结果集,也不是连接对象。


  2. 但是,我们仍然必须关闭结果集以释放一些Oracle内存。不过,如果不关闭结果集,则不会将其计算为游标。


  3. 关闭语句对象也会自动关闭结果集对象。


  4. 将为所有SELECT/INSERT/UPDATE/DELETE语句创建游标。


  5. 每个Oracle DB实例都可以使用oracle SID标识;类似地,Oracle DB可以使用连接SID标识每个连接。两个希德都不一样。


  6. 因此,Oracle会话只不过是一个JDBC(TCP)连接;它只不过是一个SID。


  7. 如果我们将最大游标设置为500,那么它只适用于一个JDBC会话/Connection/SID。
  8. 因此,我们可以使用它各自的NO游标(语句)进行许多JDBC连接。
  9. 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'

现在调试代码并享受!)


查看完整回答
反对 回复 2019-07-06
?
湖上湖

TA贡献2003条经验 获得超2个赞

请按以下方式更正您的代码:

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");
        }
    }}


查看完整回答
反对 回复 2019-07-06
  • 3 回答
  • 0 关注
  • 1113 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号