SSH框架中,服务器长时间运行后报“打开游标超出最大值”的错误。网上有说
connection.createstatement()和connection.preparestatement()打开游标后没有及时关闭的原因,但是我的程序里并没写jdbc代码。而是public class CommonBaseDaoHib extends HibernateDaoSupport,用这个CommonBaseDaoHib做数据的增删改查。高手教我~

解决方案 »

  1.   

    oracle每执行一条DML和DDL操作都是从打开游标开始的,只不过有些游标是隐式打开的,不是你程序打开的,这个时候的当DML和DDL操作执行完后,这些隐式的游标就默认的关系了,当你的同一个session打开的游标数超过了你的open_cursors参数的设置的时候就会报“打开游标超出最大值”。所以你这个时候你增加这个值的大小就行了。当然如果程序打开的游标,注意及时关闭。数据库的调优其实是亡羊补牢之策
    查看open_cursors是多少
    show parameter open_cursors;
    然后
    alter system set open_cursors=当前值+50 scope=spfile;
    最后重启系统
    startup
      

  2.   

    还有程序打开的游标是指什么?是不打开一个session就打开一个cursor?
    我不太懂。
      

  3.   

    你应该每次用CommonBaseDaoHib做数据的增删改查,后要释放你的资源,比如 preparestatement 等
      

  4.   

    不对你的理解错误如果及时关闭同一个session在统一时间的游标数可以控制。你的游标数如果一直不关闭,你的理解正确。。你可以做个statpack报告看下
      

  5.   

    一个session可以打开多个游标,但是不能超过你的open_cursors
    每个session打开的游标数目,lz也许可以观察你的这个表看是数目sql打开的游标过多,优化下,呵呵。。可能记录比较多
    select * from v$open_cursor
      

  6.   

    是向这样么?getHibernateTemplate().getSessionFactory().getCurrentSession().clear();
      

  7.   

    select pm.mosquito_id as lid, 
           pm.monitor_year || '-' || pm.monitor_month || '-' ||decode(pm.monitor_ten_days, '01','上旬','02','下旬') as monitortime,
           decode(pm.biotope, '01', '人房', '02', '畜圈') biotopes,
           z.cnname as county,
           pm.report_unit,
           coalesce(pmi1.dskw , 0) dskw,
           coalesce(pmi1.sdykw , 0) sdykw,
           coalesce(pmi1.zhaw , 0) zhaw,
           coalesce(pmi1.zjkw , 0) zjkw,
           coalesce(pmi1.sraw , 0) sraw,
           coalesce(pmi1.bwyw , 0) bwyw,
           coalesce(pmi1.qt , 0) qt,
           (select [ORGCODE] from dual) orgcode
      from pidera_mosquito pm
      left join (select pmi.mosquito_reference_id,
           sum(coalesce(decode(pmi.mosquito_name, '01', pmi.mosquito_num),0)) dskw,
           sum(coalesce(decode(pmi.mosquito_name, '02', pmi.mosquito_num),0)) sdykw,
           sum(coalesce(decode(pmi.mosquito_name, '03', pmi.mosquito_num),0)) zhaw,
           sum(coalesce(decode(pmi.mosquito_name, '04', pmi.mosquito_num),0)) zjkw,
           sum(coalesce(decode(pmi.mosquito_name, '05', pmi.mosquito_num),0)) sraw,
           sum(coalesce(decode(pmi.mosquito_name, '06', pmi.mosquito_num),0)) bwyw,
           sum(coalesce(decode(pmi.mosquito_name, '07', pmi.mosquito_num),0)) qt
       from pidera_mosquito_info pmi
       group by pmi.mosquito_reference_id) pmi1
        on (pm.mosquito_id = pmi1.mosquito_reference_id)
      join zonecode z
        on z.zonecode = pm.zonecode
     where pm.del_state != '1'
          and [DISTRICT]
          and [ZONECODE]
          and [STARTDATE]
          and [ENDDATE]
    这样一条sql怎么优化?实在找不到原因了。
      

  8.   

    这个问题应该是打开的cursor没及时关闭造成的.
    普通sql的游标oracle会自动关闭.
    检查下程序中打开的cursor是否有及时close
      

  9.   

    哪些算是程序里打开的cursor?能不能举个例子?小弟比较愚笨。。
      

  10.   

    比如在plsql里会使用open cursorname来打开一个定义的游标.
    这时候就要使用close cursorname在使用完游标后关闭游标.如果没关闭,那么多运行几次就会超出oracle对每个session的open_cursor上限.
      

  11.   

    select sid,sql_text from v$open_cursors
    这里查询出来的sql不都是打开的sql吗?
      

  12.   

    看看那些sql的数量比较多.
    SELECT *
      FROM v$open_cursor t
     WHERE t.sid IN
           (SELECT t.sid
              FROM v$open_cursor t
             GROUP BY t.sid
            HAVING COUNT(*) >= (SELECT VALUE
                                 FROM v$parameter t
                                WHERE t.NAME = lower('OPEN_CURSORS')));
      

  13.   

    把sql给前台程序开发人员,让他们查查.看是否程序中处理不当.
      

  14.   

    前几天我们系统也出现了这个问题,其实主要是因为java代码中一些数据库资源没有及时关闭造成的,例如:preparedstatement、resultset等,这里得仔细看代码是否完全关闭了你创建的这些资源,只增大cursor上限正如你说的治标不治本!
      

  15.   

    我们代码里没用到preparedstatement、resultset这些东西。。