国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

處理超出打開游標(biāo)的最大數(shù)異常

2019-11-18 15:36:02
字體:
供稿:網(wǎng)友

    在執(zhí)行如下代碼時,經(jīng)常會出現(xiàn)ora-01000: maximum open cursors exceeded異常
for(int i=0;i<balancelist.size();i++)
{
    PRepstmt = conn.prepareStatement(sql[i]);

    prepstmt.setBigDecimal(1,nb.getRealCost());
    prepstmt.setString(2, adclient_id);
    prepstmt.setString(3, daystr);
    prepstmt.setInt(4, ComStatic.portalId);
    prepstmt.executeUpdate();
}

   1. 檢查數(shù)據(jù)庫中的 OPEN_CURSORS 參數(shù)值。
Oracle 使用 init.ora 中的初始化參數(shù) OPEN_CURSORS 指定一個會話一次最多可以擁有的游標(biāo)數(shù)。缺省值為 50。要獲得數(shù)據(jù)庫中 OPEN_CURSORS 參數(shù)的值,可以使用以下查詢:   
SQL> show parameter open_cursors; 
NAME                                 TYPE        VALUE 
------------------------------------ ----------- --------------- 
open_cursors                         integer     1000   

重要的是將 OPEN_CURSORS 的值設(shè)置得足夠大,以避免應(yīng)用程序用盡所有打開的游標(biāo)。應(yīng)用程序不同,該值也不同。即便會話打開的游標(biāo)數(shù)未達(dá) OPEN_CURSORS 指定的數(shù)量(即設(shè)置的值高于實際需要的值), 也不會增加系統(tǒng)開銷。
  2. 獲取打開的游標(biāo)數(shù)。
下面的查詢按降序顯示用戶“SCOTT”為每個會話打開的游標(biāo)數(shù)。  
SQL> select o.sid, osuser, machine, count(*) num_curs
  2  from v$open_cursor o, v$session s
  3  where user_name = 'SCOTT' and o.sid=s.sid 
  4  group by o.sid, osuser, machine
  5 order by  num_curs desc; 
   SID OSUSER       MACHINE           NUM_CURS 
----------------------------------------------------- 
       217           m1                1000
        96           m2                10 
       411           m3                10 
        50          test                9 
請注重,v$open_cursor 可以跟蹤會話中 PARSED 和 NOT CLOSED 的動態(tài)游標(biāo)(使用 dbms_sql.open_cursor() 打開的游標(biāo))。它不會跟蹤未經(jīng)分析(但已打開)的動態(tài)游標(biāo)。在應(yīng)用程序中使用動態(tài)游標(biāo)并不常見。本模式的前提是未使用動態(tài)游標(biāo)。 
  3. 獲取為游標(biāo)執(zhí)行的 SQL。
使用在以上查詢結(jié)果中找到的 SID 運行下面的查詢:
SQL> select q.sql_text 
  2  from v$open_cursor o, v$sql q
  3  where q.hash_value=o.hash_value and o.sid = 217;
SQL_TEXT 
select * from empdemo where empid='212' 
select * from empdemo where empid='321' 
select * from empdemo where empid='947' 
select * from empdemo where empid='527' 
...
結(jié)果將顯示正在連接上執(zhí)行的查詢。它提供了一個入手點,讓您可以反向跟蹤到打開游標(biāo)的來源。

這樣的錯誤很輕易出現(xiàn)在java代碼中的主要原因是:Java代碼在執(zhí)行conn.createStatement()和conn.prepareStatement()的時候,實際上都是相當(dāng)與在數(shù)據(jù)庫中打開了一個cursor。尤其是,假如你的createStatement和prepareStatement是在一個循環(huán)里面的話,就會非常輕易出現(xiàn)這個問題。因為游標(biāo)一直在不停的打開,而且沒有關(guān)閉。
一般來說,我們在寫Java代碼的時候,createStatement和prepareStatement都應(yīng)該要放在循環(huán)外面,而且使用了這些Statment后,及時關(guān)閉。最好是在執(zhí)行了一次executeQuery、executeUpdate等之后,假如不需要使用結(jié)果集(ResultSet)的數(shù)據(jù),就馬上將Statement或PreparedStatement關(guān)閉。
對于出現(xiàn)ORA-01000錯誤這種情況,單純的加大open_cursors并不是好辦法,那只是治標(biāo)不治本。實際上,代碼中的隱患并沒有解除。 
而且,絕大部分情況下,open_cursors只需要設(shè)置一個比較小的值,就足夠使用了,除非有非常非凡的要求。
    假如你不使用連接池,那么就沒有什么問題,一旦Connection關(guān)閉,數(shù)據(jù)庫物理連接就被釋放,所有相關(guān)Java資源也可以被GC回收了。 
但是假如你使用連接池,那么請注重,Connection關(guān)閉并不是物理關(guān)閉,只是歸還連接池,所以PreparedStatement和ResultSet都被持有,并且實際占用相關(guān)的數(shù)據(jù)庫的游標(biāo)資源,在這種情況下,只要長期運行,往往就會報“游標(biāo)超出數(shù)據(jù)庫答應(yīng)的最大值”的錯誤,導(dǎo)致程序無法正常訪問數(shù)據(jù)庫。
正確的代碼,如下所示:
for(int i=0;i<balancelist.size();i++)
{
    prepstmt = conn.prepareStatement(sql[i]);
    prepstmt.setBigDecimal(1,nb.getRealCost());
    prepstmt.setString(2, adclient_id);
    prepstmt.setString(3, daystr);
    prepstmt.setInt(4, ComStatic.portalId);
    prepstmt.executeUpdate();
  prepstmt.close();
}



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 富锦市| 鹤庆县| 泉州市| 绥芬河市| 九台市| 桃园县| 新营市| 涪陵区| 伽师县| 尼木县| 浦江县| 凤山市| 柳林县| 团风县| 手游| 东乌珠穆沁旗| 桂平市| 太保市| 遵义县| 唐海县| 拉萨市| 张掖市| 连山| 灵台县| 高青县| 山西省| 科技| 丰原市| 密山市| 习水县| 壶关县| 姚安县| 嘉善县| 清涧县| 梁山县| 大安市| 拉萨市| 长丰县| 万荣县| 常德市| 安徽省|