天道酬勤

          沒有成功,說明努力還不夠!
          隨筆 - 2, 文章 - 0, 評論 - 29, 引用 - 0
          數據加載中……

          關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)

          昨天在開發過程中,經常碰到ORA-01000: maximum open cursors exceeded這個錯誤。一看報錯,知道是游標超過最大數了,以前在做DB2開發的時候,也曾遇到過類似的問題。雖然解決了,但一直沒弄清楚,JDBC是如何和數據庫發生交互的?又是在什么時候打開數據庫游標的?腦袋就跟漿糊一樣,說來真是慚愧啊

          昨天google了一把,終于解開一點迷惑了。

          下面的片斷轉載于www.itpub.net

          [TIP]關于Java開發中使用Oracle數據庫的一點注意事項(原創)

          很多朋友在Java開發中,使用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只需要設置一個比較小的值,就足夠使用了,除非有非常特別的要求。

          我昨天犯的錯誤就是把創建statement放到了循環之內,結果導致cursor猛增,到達了數據庫設置的最大數。
          雖然解決了問題,也清楚了游標是何時創建的,但還有幾個問題比較迷糊。
          1、通過查詢,JDBC是將所有的查詢結果一次性放到ResultSet中,還是一次只放一定數目的記錄?例如,查詢結果為2000條數據,JDBC是一次性將2000條數據放到結果集中,還是分批放置呢?

          2、當通過ResultSet.next(),移動結果集指針時,此時是否還與數據庫發生交互?

          posted on 2005-01-27 10:15 候鳥南飛 閱讀(52605) 評論(27)  編輯  收藏

          評論

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          連接和statement使用完畢之后應該及時關閉,這個應該是粉簡單的道理吧.
          2005-01-27 10:53 | eamoi

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          鳥人
          還沒回到阿?
          2005-02-17 21:33 | 不至于

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   


          2005-03-29 15:05 |

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          The article is great. I got the same error and keep scratching my head till I found your page. Keep it up!
          2005-04-28 15:39 | San

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          繼續下去啊。這個問題應該是一個比較典型的問題了吧,繼續討論阿
          2005-05-10 18:27 | 芨芨草

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          pst.close();
          rs.close();

          只要及時關閉應該就可以了吧?
          2005-07-05 15:23 | plutohades

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          首先結果集resultset在你的java程序處。其中有個fetchsize設置,這個表示每次從數據庫處取多少條記錄到resultset.
          2006-03-14 09:42 |

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          當通過ResultSet.next(),移動結果集指針時,此時是否還與數據庫發生交互?

          不發生交互,數據庫執行完查詢后,已經把查詢結果交給ResultSet了,以后的操作,和數據庫無關。
          2006-03-15 10:26 | jing

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          交互,如果1個查詢有10000條記錄,resultset中只有fetchsize條,當next時還會在一定時機去交互
          2006-03-17 10:44 |

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          白是對的。
          2006-05-08 09:27 | 阿黑

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          非常感謝!
          2006-05-12 15:00 | 感謝

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          暈。。。。。。。。。
          2006-05-18 15:50 | 順哥

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          一搜索這個問題竟然到了你的blog,真是冤孽啊。。:)
          2006-05-18 15:51 | 順哥

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          不是將查詢結果一次性放到ResultSet中, 而是分批放入ResultSet中,一般情況下是每次10條記錄.
          當通過ResultSet.next(),移動結果集指針時,此時還會與數據庫發生交互.

          導致maximum open cursors exceeded這個問題一般是代碼本身的問題.
          比如執行一個查詢沒有關閉游標,或是在存儲過程中打開了游標而沒有關閉.
          特別是出現異常情況是沒有關閉游標.嚴重時會導致系統崩掉
          2006-06-01 03:58 | sheen

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          我也是同樣的問題,但我開發語言是用DELPHI,使用組件是ADOQUERY,游標超過最大數困擾我好久了,如果有誰知道,請告之jxprovince@mail.china.com
          2006-06-18 17:42 | JXPROVINCE

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          啊~!~`我剛也犯了這種錯誤!!``看到這里的貼子,小妹又明白了:"哦!``原來conn.createStatement()和conn.prepareStatement()的時候實際上都是相當與在數據庫中打開了一個cursor。!!"明白了這點過后,我就在循環里新建一個prepareStatement對象,操作完一次,成功過后就馬上關掉!這樣,循環里每次一個insert都新new 一個prepareStatement 操作成功完成之后再馬上關閉.嘎嘎.~這樣,cursor就不會溢出拉.
          2007-01-11 09:55 | 子圓

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          我遇到的就是這個問題,看了你的文章終于明白了
          2007-03-07 18:20 | vingle

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          有時候出于性能方面的考慮,多個用戶使用一個數據庫連接,這時一定要及時關閉cursor,否則就會報這個錯。
          2007-06-15 11:15 | fenix

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          當通過ResultSet.next(),移動結果集指針時,此時是否還與數據庫發生交互?


          不與數據庫交互,此時數據集拿到一個collection中,ResultSet就是一個collectin是實現
          2007-07-11 18:00 | cshbl@hotmail.com

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          3ks
          2007-10-11 18:06 | zhangyangbin

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          謝謝
          犯了跟你一樣的錯
          2008-09-01 10:03 | nijj

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          你是對的...
          2008-12-16 18:47 | 豬頭

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)[未登錄]  回復  更多評論   

          我的問題還是這個,但是估計你沒有回答到點子上。
          我在開發過程中,本身用Hibernate3應該完全不用我們干預Session的工作吧,要不還要它作甚?
          我的測試系統在MYSQL數據庫上從來不會出現這個問題,但是切換到生產系統,除了數據庫URL和方言配置改成ORACLE外,其他全部不變,但是它就是出了這個ORA-01000,這不是逼著我不用這個破Hibernate嘛
          2009-06-02 08:10 | 明明

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)[未登錄]  回復  更多評論   

          好像是這樣的,出現了同樣的報錯,看程序也是在循環里面prepareStatement
          2009-08-10 10:41 | 111

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          ResultSet不是與數據庫的一個映射關系嗎,rs.close()之后,ResultSet.next()不行吧....
          2010-08-12 11:40 | 任李菲

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          剛好碰到了這個問題,謝了、、、
          2011-02-28 16:02 |

          # re: 關于ORACLE游標的問題(ORA-01000: maximum open cursors exceeded)  回復  更多評論   

          只要不循環或者過多的創建statement就行了,一般寫循環邏輯會出現這類問題。
          有些人提到jpa類的框架,這種情況如果出現不是框架的問題,而是使用方法不得當造成的,statement的類型選擇或者sql的結構優化不對,導致statement創建過多。

          next是否跟數據庫交互,取決于你的fetchsize
          2011-03-16 17:25 | 王志猛

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 太白县| 瓮安县| 新竹县| 青海省| 垦利县| 探索| 昌黎县| 白玉县| 太仓市| 泸定县| 凤翔县| 手机| 巴林右旗| 威远县| 汉源县| 修水县| 阜康市| 新营市| 青河县| 花莲县| 镇巴县| 宁乡县| 汪清县| 丽江市| 安阳县| 忻州市| 漠河县| 江口县| 红安县| 新源县| 蓬莱市| 清镇市| 商都县| 东兴市| 公主岭市| 峡江县| 黄冈市| 十堰市| 永宁县| 阿拉善盟| 石首市|