Oracle database link中查詢會開啟事務嗎?


關於oracle database link,使用database link相關的查詢語句是否會開啟事務呢?我們知道,在數據庫中一個簡單的SELECT查詢語句不會產生事務(select for update會產生事務)。如下測試所示:

 

 

clip_image001

 

我們首先准備測試環境,創建了一個database link: LINK_NODEFINE_TEST,然后我們開始測試

 

CREATE PUBLIC DATABASE LINK LINK_NODEFINE_TEST
CONNECT TO TEST IDENTIFIED BY "t123$%^" 
USING '(DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.57.24)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = gsp.localdomain)
    )
  )';

 

 

下面開始演示一下database link相關的查詢是否會開啟事務:

 

SQL> show user;
USER is "SYS"
SQL> select userenv('sid') from dual;
 
USERENV('SID')
--------------
           939
 
SQL> select xidusn, xidslot, xidsqn  
  2  from v$transaction, v$session  
  3  where saddr=ses_addr;
 
no rows selected
 
SQL> select * from kerry@link_nodefine_test;
 
        ID NAME
---------- --------------------------------
       100 kerry
 
SQL> select xidusn, xidslot, xidsqn  
  2  from v$transaction, v$session  
  3  where saddr=ses_addr;
 
    XIDUSN    XIDSLOT     XIDSQN
---------- ---------- ----------
         3         14    4122050
 
SQL> alter session close database link link_nodefine_test;
ERROR:
ORA-02080: database link is in use
 
 
SQL> commit; --必須要先commit,才能關閉鏈接
 
Commit complete.
 
SQL> alter session close database link link_nodefine_test;
 
Session altered.

 

下面我們創建一個賬號TEST,測試驗證database link所指向遠程數據庫中會話的生存周期,簡單測試,你會發現即使一個簡單查詢(包含database link),會在遠程數據庫生成一個會話。而且如果不執行alter session close database link xxx關閉對應的database link的話,該會話不會銷毀,而是變成INACTVIE狀態。直到其觸發了TCP keepalive相關機制后才會被數據庫清理。

 

clip_image002

 

 

一旦你執行了database link相關的查詢,  那么在遠程數據庫(10.20.57.24)這個測試服務器的數據庫實例中,就會生成對應的會話,而且只有在原數據庫執行了alter session close database link link_nodefine_test"后,對應的會話才會銷毀(當然,觸發了TCP keepalive相關機制后也會被數據庫清理)。有興趣可以自行測試。

 

SQL> select count(*) from v$session where username='TEST';
 
  COUNT(*)
----------
         1
 
SQL> select count(*) from v$session where username='TEST';
 
  COUNT(*)
----------
         0
 
SQL> 

 

那么問題來了,如果我在會話當中多次使用select * from kerry@link_nodefine_test這類包含database link的語句,是否會在10.20.57.24生成多個會話呢? 還是說這個database link相關的會話會復用呢? 下面我們測試驗證一下:

 

如下所示,同一個會話當中多次使用database link查詢,不會在10.20.57.24生成多個會話。 但是如果多個不同會話中都使用database link link_nodefine_test的話,那么就會在(10.20.57.24)中生成多個會話

 

 

clip_image003

 

 

那么如果在同一個會話中,使用不同的database link,但是這兩個database link使用相同的賬號,指向相同的服務器,那么這個是否也共用一個會話呢?答案是不會,而是會生成新的會話。如下測試所示

 

CREATE PUBLIC DATABASE LINK LINK_DEDIATED_TEST
CONNECT TO TEST IDENTIFIED BY "t123$%^" 
USING '(DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.57.24)(PORT = 1521))
    )
    (CONNECT_DATA =
       (SERVER = DEDICATED)
      (SERVICE_NAME = gsp.localdomain)
    )
  )';

 

 

clip_image004

 

關於dblink的查詢為什么產生事務的原理分析,參考官方文檔Transaction Processing in a Distributed System

 

 

Two-Phase Commit Mechanism

 

A database must guarantee that all statements in a transaction, distributed or non-distributed, either commit or roll back as a unit. The effects of an ongoing transaction should be invisible to all other transactions at all nodes; this transparency should be true for transactions that include any type of operation, including queries, updates, or remote procedure calls.

 

The general mechanisms of transaction control in a non-distributed database are discussed in the Oracle Database Concepts. In a distributed database, the database must coordinate transaction control with the same characteristics over a network and maintain data consistency, even if a network or system failure occurs.

The database two-phase commit mechanism guarantees that all database servers participating in a distributed transaction either all commit or all roll back the statements in the transaction. A two-phase commit mechanism also protects implicit DML operations performed by integrity constraints, remote procedure calls, and triggers.

 

 

總結:

 

Oracle數據庫中使用dblink的相關查詢語句會產生事務, 如果有大量會話使用dblink的話,會在遠程數據庫產生大量的會話,有時候消耗的連接數量會非常可觀。對於dblink在遠程數據庫的會話,必須先在本地數據庫的當前會話commit,然后alter session close database link xxx, 關閉dblink,如果不執行這些操作,只能靠DCD或Tcp KeepLive機制觸發數據庫銷毀會話。

 

 

 

參考資料:

 

 

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:393468893370

http://blog.itpub.net/267265/viewspace-2123710/

https://docs.oracle.com/cd/B28359_01/server.111/b28310/ds_concepts004.htm#ADMIN12120

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM