1. 程式人生 > >oracle ORA-01000: maximum open cursors exceeded問題的解決方法

oracle ORA-01000: maximum open cursors exceeded問題的解決方法

專案在執行過程中,後臺報錯:   

ORA-01000: maximum open cursors exceeded  
ORA-00604: error occurred at recursive SQL level 1  

      網上搜索了一下,找到了原因根源:

  使用Oracle資料庫的時候,經常會碰到有ORA-01000: maximum open cursors exceeded的錯誤。實際上,這個錯誤的原因,主要還是程式碼問題引起的。  

  ora-01000: maximum open cursors exceeded:表示已經達到一個程序開啟的最大遊標數。

  這樣的錯誤很容易出現在Java程式碼中的主要原因是:Java程式碼在執行conn.createStatement()和conn.prepareStatement()的時候,實際上都是相當與在資料庫中打開了一個cursor。尤其是,如果你的createStatement和prepareStatement是在一個迴圈裡面的話,就會非常容易出現這個問題。因為遊標一直在不停的開啟,而且沒有關閉。

  一般來說,我們在寫Java程式碼的時候,createStatement和prepareStatement都應該要放在迴圈外面,而且使用了這些Statment後,及時關閉。最好是在執行了一次executeQuery、executeUpdate等之後,如果不需要使用結果集(ResultSet)的資料,就馬上將Statment關閉。

  對於出現ORA-01000錯誤這種情況,單純的加大open_cursors並不是好辦法,那只是治標不治本。實際上,程式碼中的隱患並沒有解除。

  而且,絕大部分情況下,open_cursors只需要設定一個比較小的值,就足夠使用了,除非有非常特別的要求。

解決方案 

一、從源頭上解決方案(建議)

  檢查程式碼,把涉及到開啟連結的地方,用完之後,千萬別忘記關掉。

二、臨時解決方案(不建議)

  通過修改oracle系統引數:將OPEN_CURSORS 的值設定得足夠大,以避免應用程式用盡所有開啟的遊標。應用程式不同,該值也不同。即便會話開啟的遊標數未達 OPEN_CURSORS 指定的數量(即設定的值高於實際需要的值), 也不會增加系統開銷。 

步驟如下:

複製程式碼

--第一步:檢視當前OPEN_CURSORS 的值 

SQL> show parameter open_cursors;  

NAME                                 TYPE        VALUE ------------------------------------ 
open_cursors                         integer     300


--第二步:檢視修改之後是重啟oracle服務生效還是立即生效

SQL> show parameter spfile;  

NAME                                 TYPE        VALUE ------------------------------------ 
spfile                               string      /home/oracle/oracle/product/10.2.0/db_1/dbs/spfileeeim.ora

 

--第三步:修改遊標:open_cursors的值  

SQL> alter system set OPEN_CURSORS=1200; 

System altered

複製程式碼

補充:修改系統引數時,scope有三個重要引數,如下:(我這裡因為引數原本就是spfile,所以沒有這步,如果需要這步,這步應該在第三步之前執行)

alter system set parameter= value scope=spfile;  

SCOPE=MEMORY:只改變當前例項執行,亦即初始化引數改變了只對當前例項有效,當例項重啟之後,初始化引數值還原。

SCOPE=SPFILE:只改變SPFILE的設定。亦即改變初始化引數檔案內容。例項重啟後引數生效。

SCOPE=BOTH:既改變例項也改變SPFILE。指定這個選項相當於不帶引數的alter system語句。需要注意的是,如果修改靜態引數,必須指定SPFILE引數(必須表明SCOPE=MEMOEY或者SCOPE=SPFILE),否則會報錯。