天天看點

Oracle調用接口(OCI)源碼剖析(1):建立資料庫連接配接

概述

在筆者所開發過的産品中,有很多都需要與Oracle資料庫打交道。為了實作C代碼與Oracle資料庫的消息互動,Oracle公司為廣大的開發者們提供了一個統一的調用接口OCI(Oracle Call Interface)。隻要按照規範來調用OCI中的函數,就能夠實作C代碼與Oracle資料庫的互動。

具體而言,OCI的C語言API包括了兩個檔案:db_ora_oci_ux.h和db_ora_oci_ux.c。db_ora_oci_ux.h是頭檔案,而所有與資料庫的互動操作的實作都是在db_ora_oci_ux.c中完成的。

本文對OCI的建立資料庫連接配接操作的源碼進行簡單的剖析。

OCI中建立資料庫連接配接的源碼剖析

在OCI中,建立資料庫連接配接的操作是由CDbCreateDb函數實作的,其代碼如下:

從該函數的代碼實作中,我們可以看到:

1)建立資料庫連接配接包括這幾步操作:第一步,申請句柄指針空間;第二步,初始化資料庫連接配接;第三步,建立結果集。

2)申請句柄指針空間操作是由OsGetUB函數實作的,初始化資料庫連接配接操作是由DoDbInit函數實作的,建立結果集操作是由DoRecInit函數實作的。

3)為了防止在多個流程中同時調用該函數,在初始化資料庫連接配接之前采用了加鎖操作,這保證了每一個建立資料庫的操作所傳回的句柄是唯一的。

4)如果初始化資料庫連接配接操作函數DoDbInit執行失敗了,程式就會執行OsRetUB函數來釋放句柄指針空間(該操作與之前的申請句柄指針空間操作對應起來)。

5)如果建立結果集操作函數DoRecInit執行失敗了,程式除了執行OsRetUB函數來釋放句柄指針空間之外,還會執行DoDbFree函數來釋放資料庫連接配接(該操作與之前的初始化資料庫連接配接操作對應起來)。

初始化資料庫連接配接操作函數DoDbInit的代碼如下:

下面對DoDbInit函數進行分析:

1)該函數的執行流程是這樣的:第一步,申請所有句柄指針儲存空間;第二步,建立OCI環境;第三步,申請錯誤句柄;第四步,申請伺服器句柄;第五步,申請服務環境句柄;第六步,連接配接資料庫;第七步,設定服務環境的伺服器屬性;第八步,申請使用者會話句柄,第九步,設定會話所使用的使用者帳戶和密碼;第十步,建立資料庫操作會話;第十一步,設定會話服務環境。

2)實作以上十一步操作的函數均是OCI底層提供的(都以OCI打頭)。不管哪一步操作執行失敗,都會輸出相關的日志,可供排查問題。

3)所有OCI主要句柄資料結構OCIHDBC的實作如下:

以上不同的操作是對OCIHDBC結構體中對應的句柄指派。

建立結果集操作函數DoRecInit的代碼如下:

下面對DoRecInit函數進行分析:

1)該函數的作用是初始化結果集,首先,該函數執行OsGetUB函數申請句柄指針空間,然後執行memset函數初始化結果集。

2)結果集結構體CDbRecordset的代碼如下:

如果後續操作要從資料庫中擷取資料,那麼這些資料就用CDbRecordset結構體來存儲。

釋放資料庫連接配接操作函數DoDbFree的代碼如下:

從代碼可以看出,該函數的功能是依次釋放在DoDbInit函數中所申請的句柄指針。所有的以OCI開頭的函數都是OCI底層提供的。

建立資料庫連接配接函數CDbCreateDb的調用

在我們編寫C代碼建立資料庫連接配接的時候,隻需要将db_ora_oci_ux.h檔案頭包括進來,同時直接調用CDbCreateDb函數就可以了。

示例代碼如下:

說明:

1)CDbCreateDb函數的五個輸入參數分别是:資料庫類型、資料庫服務名、資料庫名、使用者名和密碼。除了資料庫類型之外,其他幾個參數都和具體的資料庫有關,需要在安裝Oracle資料庫的時候進行設定。

2)隻有在資料庫句柄配置設定成功(也就是資料庫連接配接建立成功)的情況下,程式才能執行後續操作;如果資料庫句柄配置設定失敗,要及時找到失敗原因。