關於ORA-02020: 過多的資料庫連結在使用中 錯誤的進階研究

lnwxzyp發表於2009-12-28
    最近遇到了ORA-02020的錯誤,通過對這一錯誤的解決,終於搞懂了一些深層次的東西。
首先檢視資料庫的相關引數:(tool:PL/SQL Developer→command window)
SQL> show parameter open_links

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
open_links                           integer     4

這個引數是說允許4個資料庫連線同時開啟。 為此進行測試:
(tool:PL/SQL Developer→command window)

SQL> SELECT * FROM dual@link_1;

DUMMY
-----
X

SQL> SELECT * FROM dual@link_2;

DUMMY
-----
X

SQL> SELECT * FROM dual@link_3;

DUMMY
-----
X

SQL> SELECT * FROM dual@link_4;

DUMMY
-----
X

SQL> SELECT * FROM dual@link_5;

DUMMY
-----
X

已經使用了5個資料連線並沒有發生錯誤,換成生產當中報錯的表繼續進行測試:
(tool:PL/SQL Developer→SQL window)
SELECT * FROM log@link_1;
SELECT * FROM log@link_2;
SELECT * FROM log@link_3;
SELECT * FROM log@link_4;
SELECT * FROM log@link_5;
第五個資料連線報錯:ORA-02020: 過多的資料庫連結在使用中。經過一番測試發現log表的資料量比較大,有上萬條記錄,在執行語句之後 commit和rollback圖示就成了高亮形式,一旦第5個也會變成高亮圖示之前就會報錯 又經過測試,發現選取的記錄達到26條及以上時就會出現高亮的commit和rollbak圖示,低於26條則不會出現。但是在(tool:PL/SQL Developer→command window)下測試的時候並不報錯。
SQL> SELECT LEVEL FROM dual@link_1 CONNECT BY LEVEL<27;

     LEVEL
----------
         1
         2
       ...
        26

SQL> SELECT LEVEL FROM dual@link_2 CONNECT BY LEVEL<27;

     LEVEL
----------
         1
         2
       ...
        26

SQL> SELECT LEVEL FROM dual@link_3 CONNECT BY LEVEL<27;

     LEVEL
----------
         1
         2
       ...
        26

SQL> SELECT LEVEL FROM dual@link_4 CONNECT BY LEVEL<27;

     LEVEL
----------
         1
         2
       ...
        26

SQL> SELECT LEVEL FROM dual@link_5 CONNECT BY LEVEL<27;

     LEVEL
----------
         1
         2
       ...
        26

並沒有發生報錯的情況,同時commit和rollback的圖示也沒有發生變化,使用for update選項來進行測試 (tool PL/SQL developer→command window)

SQL> SELECT LEVEL FROM dual@dblink_1 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@dblink_2 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_3 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_4 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_5 CONNECT BY LEVEL<1 FOR UPDATE;

SELECT LEVEL FROM dual@link_5 CONNECT BY LEVEL<1 FOR UPDATE

ORA-02020: 過多的資料庫連結在使用中

這次錯誤出現了,網上查到解決的辦法:alter session close database link link_name,但是在執行之後發現報錯

SQL> SELECT LEVEL FROM dual@link_1 CONNECT BY LEVEL<1 FOR UPDATE;

SQL> ALTER SESSION CLOSE DATABASE LINK link_1;

ALTER SESSION CLOSE DATABASE LINK link_1

OORA-02080: 資料庫連結正在使用中

看到這個錯誤,我這裡實際出錯的情況是儲存過程當中多個合併查詢連線不同的資料庫,才出現了錯誤,於是繼續測試:

SQL> SELECT LEVEL FROM dual@link_1 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_2 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> ALTER SESSION CLOSE DATABASE LINK link_1;

OORA-02080: 資料庫連結正在使用中

依然還是報錯,這說明並不是多個以上在使用以後才能夠關閉資料連線,他們並不存在依賴關係。 由於是commit和rollback圖示點亮之後才出現的錯誤,於是我先嚐試對每一條語句執行後進行提交或回滾操作:

SQL> SELECT LEVEL FROM dual@link_1 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> ROLLBACK;

Rollback complete

SQL> SELECT LEVEL FROM dual@link_2 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> ROLLBACK;

Rollback complete

SQL> SELECT LEVEL FROM dual@link_3 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> COMMIT;

Commit complete

SQL> SELECT LEVEL FROM dual@link_4 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> ROLLBACK;

Rollback complete

SQL> SELECT LEVEL FROM dual@link_5 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> COMMIT;

Commit complete

SQL> SELECT LEVEL FROM dual@link_6 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> ROLLBACK;

Rollback complete

使用了6個資料連線並沒有發生報錯的情況,而這個時候使用關閉資料連線的語句也不起作用

ALTER SESSION CLOSE DATABASE LINK link_1

ORA-02081: 資料庫連結未開啟

最後進行一次測試,這次才恍然大悟:
SQL> SELECT LEVEL FROM dual@dblink_1 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@dblink_2 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_3 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_4 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> COMMIT;

Commit complete

SQL> ALTER SESSION CLOSE DATABASE LINK dblink_1;

Session altered

SQL> ALTER SESSION CLOSE DATABASE LINK dblink_2;

Session altered

SQL> ALTER SESSION CLOSE DATABASE LINK link_3;

Session altered

SQL> SELECT LEVEL FROM dual@link_4 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> SELECT LEVEL FROM dual@link_5 CONNECT BY LEVEL<1 FOR UPDATE;

     LEVEL
----------
         1

SQL> COMMIT;

Commit complete

SQL> ALTER SESSION CLOSE DATABASE LINK link_4;

Session altered

看到這裡,相信大家也明白了吧,也能夠很容易的得出結論:
1.26條以上的記錄並且在sql window視窗下(儲存過程裡面也一樣)超過4個資料庫連線,才會發生錯誤,如果沒有達到26條記錄,那麼放心的使用多個資料庫連線吧,不會有什麼影響。
2.使用alter session關閉資料連線的前提是已經有4個以內的資料庫連線”被使用“(相信大家已經明白 被使用是什麼概念)並且最近被使用的資料連線已經被提交或者回滾的情況下可以使用,否則會出現”ORA-02080: 資料庫連結正在使用中“的錯誤




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12216142/viewspace-623702/,如需轉載,請註明出處,否則將追究法律責任。

相關文章