2012-04-04 83 views
3

這裏是場景...ORACLE/ASP.NET:ORA-2020 - 數據庫鏈接太多......這是什麼原因造成的?

我們有一個內部網站運行最新版本的ODAC(Oracle客戶端)。它打開數據庫連接,運行存儲過程或打包方法,然後斷開連接。連接池已打開,目前我們在開發和測試環境下都使用11g版本,但在我們的生產環境下使用10gR2。這發生在生產上。

幾天前,一個進程開始引發ORA-2020錯誤。該流程從我們內部網站的網頁上調用。用戶只需設置日期,點擊按鈕,並在另一個與網站分開的系統上啓動作業。然而,調用本身使用數據庫鏈接來運行一個函數。

我們搜索了SQL,發現它只使用那一個數據庫鏈接。由於這些鏈接是基於每個會話並且用戶不超過默認限制4,因此我們如何獲得ORA-2020錯誤。

我們已經運行了大量的測試以試圖超過4的默認限制。從我所記得的情況來看,ODAC在每次連接後運行一次提交,並且我似乎無法運行4個數據庫鏈接,然後運行一個帶有1個數據庫鏈接的SQL,並且存在任何錯誤之後。我可以提出這個錯誤的唯一方法是如果我運行帶有4個DB鏈接的查詢,然後是一個包含數據庫鏈接的函數或動態SQL。我們沒有這個問題,因爲這個問題是零星的。這並不總是發生。

問題

  1. 是否有可能連接池是允許用戶B使用用戶A的連接的初始過程運行之後,因此增加了打開鏈接數量,如果用戶B運行在使用SQL語句更多數據庫鏈接?
  2. 這是我們應該超過4的限制嗎?增加號碼的缺點是什麼?
  3. 在從數據庫斷開連接之前,是否需要顯式關閉打開的數據庫鏈接? Oracle文檔似乎表明它應該自動發生,但「有時」......不。

回答

1

我們最終增加了鏈接數量,但我們從未找到根本原因。

2

首先,簡單的解決方案:我會仔細檢查,在生產數據庫的默認鏈接的數量是實際上 4.

select * 
    from v$system_parameter 
where name = 'OPEN_LINKS' 

假如你不打算下車即到輕輕:

是否有可能連接池是允許用戶B使用用戶 初始處理後A的連接被運行,從而增加了 打開鏈接號如果用戶B運行SQL語句與更多數據庫 鏈接?

你說你明確地關閉了會話,根據the documentation,該會話應該表示與該會話關聯的所有鏈接都關閉。除此之外,我承認在這一點上完全無知。

這是我們應該超過4的限制嗎?增加號碼的缺點是什麼?

我想不出有什麼缺點。 Tom Kyte suggests,儘管很久以前,每個打開的數據庫鏈接都使用500k的PGA內存。如果你沒有,那麼這顯然會造成一個問題,但在大多數情況下它應該是很好的。

但是,還是會有意想不到的後果:想象一下,你將這個數字提高到100.有些人編碼的東西不斷打開鏈接,並通過它們的所有select * from my_massive_table或類似的方式繪製大量數據。而不是4個會話這樣做你有100個,這是試圖同時傳輸數百GB。你的網絡在應變下死亡...

有可能更多,但你得到的圖片。

從數據庫斷開 之前,是否需要顯式關閉打開的數據庫鏈接? Oracle文檔似乎暗示應該自動發生 ,但「有時」......不。

正如你已經注意到的最好的答案是「可能不是」,這是沒有多大的幫助。你沒有提到你是如何終止會議的,但是如果你是在殺死它而不是優雅地關閉,那麼肯定會。

使用數據庫鏈接會在遠程服務器上產生子進程。因爲你的服務器不再是這個過程的絕對主管,所以有很多事情可能導致它在父進程終止時變成孤立或者不關閉。這決不是整個過程都會發生,但它可以做到。

我會做兩件事。

  1. 在您的過程中,如果遇到異常,請將以下查詢的結果通過電子郵件發送給您自己。

    select * 
        from v$dblink 
    

    至少你會知道在會話中打開了哪些數據庫鏈接,並給你一些跟蹤它們的方法。

  2. 請按照文件建議;具體如下:

    • 通過鏈路建立的網絡連接是在應用程序中不經常使用的:

      「你可能有機會手動關閉鏈路。例如,靠近 時鏈接。

    • 用戶會話必須終止。「

第一似乎正好適合你的情況。除非你的過程是時間敏感的,但似乎並非如此,那麼你有什麼損失?語法是:

alter session close database link <linkname> 
+0

經過更多測試後,第一個問題得到解答。至少在我們的11g環境中進行測試時,這絕對是不可能的。爲每個事務創建一個連接,並且ODP.NET隱式提交併且連接被關閉並放置在我們的代碼中。我們無法抓住另一個連接並使用會話。我們正在添加一些跟蹤來查看發生錯誤時鏈接是否打開。 – jlrolin 2012-04-09 18:12:59

相關問題