在 ODBC 驅動程式中開發連線集區覺察
本主題討論開發 ODBC 驅動程式的詳細資料,其中包含驅動程式應如何提供連線共用服務的相關資訊。
啟用可感知驅動程式的連線共用
驅動程式必須實作下列 ODBC 服務提供者介面 (SPI) 函數:
SQLSetConnectAttrForDbcInfo
SQLSetConnectInfo
SQLSetDriverConnectInfo
SQLGetPoolID
SQLRateConnection
SQLPoolConnect
SQLCleanupConnectionPoolID
如需詳細資訊,請參閱 ODBC 服務提供者介面 (SPI) 參考。
驅動程式也必須實作下列現有的函數,以便啟用驅動程式感知共用:
函式 | 增加的功能 |
---|---|
SQLAllocHandle SQLFreeHandle SQLGetDiagField SQLGetDiagRec |
支援新的控制代碼類型:SQL_HANDLE_DBC_INFO_TOKEN (請參閱下列描述)。 |
SQLSetConnectAttr | 支援新的僅限設定連線屬性:用於重設連線的 SQL_ATTR_DBC_INFO_TOKEN (請參閱下列說明)。 |
注意
驅動程式感知連線共用不支援已淘汰的函數,例如 SQLError 和 SQLSetConnectOption。
集區識別碼
集區識別碼是指標長度的驅動程式專用識別碼,代表可交換使用的特定連線群組。 假設有一組連線資訊,驅動程式應該能快速推斷對應的集區識別碼。
例如,集區識別碼應該將伺服器名稱和認證資訊編碼。 不過,這時不須使用資料庫名稱,因為驅動程式可能重複使用連線,然後以少於建立新連線所需的時間變更資料庫。
驅動程式應該定義一組索引鍵屬性,以此組成集區識別碼。 這些索引鍵屬性的值可能來自連線屬性、連接字串和 DSN。 如果這些來源有任何衝突,則現有的驅動程式專用解決原則應用於回溯相容性。
驅動程式管理員會針對不同的集區識別碼使用不同的集區。 相同集區中的所有連線都可重複使用。 驅動程式管理員永遠不會重複使用具不同集區識別碼的連線。
因此,驅動程式應該為其定義索引鍵屬性中,具有相同值的每個連線群組指派唯一的集區識別碼。 如果驅動程式針對索引鍵屬性中,具有不同值的兩個連線使用相同的集區識別碼,驅動程式管理員仍會將這兩個連線放入相同的集區 (驅動程式管理員不會知道驅動程式專用的索引鍵屬性)。 這表示,驅動程式必須向驅動程式管理員回報,有一組具不同索引鍵屬性的連線無法在 SQLRateConnection 函數內重複使用。 這可能會降低效能,因此不建議這麼做。
即使所有連線資訊都相符,驅動程式管理員也不會重複使用從另一個驅動程式環境配置的連線。 即使連線具有相同集區識別碼,驅動程式管理員也會針對不同的環境使用不同的集區。 因此,集區識別碼是其驅動程式環境的本機設定。
SQLGetPoolID 函數是可從驅動程式取得集區識別碼的函數。
連線評等
相較於建立新的連線,若您重設一些連線資訊 (例如集區連線中的 DATABASE) ,可達到更優異的效能。 因此,您可能不希望資料庫名稱位於索引鍵屬性的集合。 否則,您可以針對每個資料庫使用不同的集區,這可能不適用於中間層應用程式,因為客戶會在其中使用各種不同的連接字串。
只要您重複使用的連線有屬性不符的問題,您就應該根據新的應用程式要求重設不相符的屬性,讓傳回的連線與應用程式要求相同 (請參閱 SQLSetConnectAttr 函數 中,針對屬性 SQL_ATTR_DBC_INFO_TOKEN 的討論)。 不過,重設這些屬性可能會降低效能。 例如,重設資料庫需要對伺服器進行網路呼叫。 因此,如果有完全相符的連線,請重複使用。
驅動程式中的評等函式可以使用新的連線要求,來評估現有的連線。 例如,驅動程式的評等函式可以判斷:
現有的連線是否與要求完全相符。
是否只有一些不重要的不符問題,例如連線逾時,且無須與伺服器通訊即可重設。
是否有一些不相符的屬性,必須與伺服器進行重設通訊,但仍可達到比建立新連線更高的效能。
需要耗費大量時間重設的屬性,是否有不符的問題 (驅動程式的開發人員可能會考慮將此屬性新增至索引鍵屬性集合,以用來產生集區識別碼)。
評等結果可能得出 0 到 100 之間的分數,其中 0 表示不重複使用,100 表示完全相符。 SQLRateConnection 是用於評等連線的函數。
新的 ODBC 控制代碼 - SQL_HANDLE_DBC_INFO_TOKEN
為了支援驅動程式感知連線共用,驅動程式需要連線資訊來計算集區識別碼。 驅動程式也需要連線資訊,才能比較新的連線要求與集區中的連線。 若集區中沒有任何連線可重複使用,驅動程式就必須建立新的連線,因此需要連線資訊。
由於連線資訊可能來自多個來源 (連接字串、連線屬性和 DSN),因此驅動程式可能需要剖析連接字串,並解決上述每個函式呼叫中,這些來源之間的衝突。
因此,引進了新的 ODBC 控制代碼:SQL_HANDLE_DBC_INFO_TOKEN。 使用 SQL_HANDLE_DBC_INFO_TOKEN 時,驅動程式不需要剖析連接字串,也不須多次解決連線資訊中的衝突。 由於這是驅動程式專用的資料結構,因此驅動程式可以儲存連線資訊或集區識別碼等資料。
此控制代碼只會作為驅動程式管理員與驅動程式之間的介面使用。 應用程式無法直接配置此控制代碼。
這個控制代碼的父代控制代碼類型為 SQL_HANDLE_ENV,這表示驅動程式可以在連線資訊解析期間,從 HENV 控制代碼取得環境資訊。
每次收到新的連線要求時,驅動程式管理員會在確認驅動程式支援連線集區感知之後,配置類型為 SQL_HANDLE_DBC_INFO_TOKEN 的控制代碼來儲存連線資訊。 使用控制代碼後 (但在傳回 SQLDriverConnect 或 SQLConnect 的 SQL_STILL_EXECUTING 以外的部分傳回碼之前),驅動程式管理員會釋放控制代碼。 因此,控制代碼會在 SQLAllocHandle 呼叫之後建立,並在 SQLFreeHandle 呼叫之後終結。 SQLDriverConnect 或 SQLConnect 傳回錯誤時,驅動程式管理員會先保證控制代碼能釋放,再釋放其相關聯的 HENV。
驅動程式應該修改下列函數,以接受新的控制代碼類型SQL_HANDLE_DBC_INFO_TOKEN:
驅動程式管理員會保證多個執行緒不會同時使用相同的 SQL_HANDLE_DBC_INFO_TOKEN 控制代碼。 因此,此控制代碼的同步處理模型在驅動程式內可能非常簡單。 在配置和釋放 SQL_HANDLE_DBC_INFO_TOKEN 之前,驅動程式管理員不會進行環境鎖定。
驅動程式管理員的 SQLAllocHandle 和 SQLFreeHandle 不接受這個新的控制代碼類型。
SQL_HANDLE_DBC_INFO_TOKEN 可能包含機密資訊,例如認證。 因此,驅動程式應以安全方式清除包含敏感資訊的記憶體緩衝區 (使用 SecureZeroMemory),再以 SQLFreeHandle 釋出此控制代碼。 應用程式的環境控制代碼關閉時,所有相關聯的連線集區也都會關閉。
驅動程式管理員連線集區評等演算法
本節討論驅動程式管理員連線共用的評等演算法。 驅動程式開發人員可以實作相同的演算法來回溯相容性。 此演算法可能不是最佳演算法。 您應該根據實作情況來精簡此演算法 (否則就不需要實作此功能)。
驅動程式管理員會針對集區的每個連線,傳回分數為 0 到 100 之間的整數評等。 0 表示無法重複使用連線,100 表示完全相符。 假設連線要求名為 hRequest,而集區中的現有連線命名為 hCandidate。 如果下列任一條件為 false,則無法針對 hRequest 重複使用集區連線 hCandidate (驅動程式管理員會指派 0 分評等)。
hCandidate 和 hRequest 都來自 UNICODE API (例如 SQLDriverConnectW) 或 ANSI API (例如 SQLDriverConnectA)。 (在給定 ANSI API 和 UNICODE API 的情況下,UNICODE 驅動程式可能有不同的行為,請參閱連線屬性 SQL_ATTR_ANSI_APP)
hCandidate 和 hRequest 都是由相同的函數所建立,即 SQLDriverConnect 或 SQLConnect。
使用 SQLDriverConnect 時,用來開啟 hCandidate 的連接字串應該與 hRequest 相同。
使用 SQLConnect 時,ServerName (或 DSN)、使用者名稱和用來開啟 hCandidate 的密碼,都應與開啟 hRequest 的相同。
目前執行緒的安全性識別碼 (SID) 應與用來開啟 hCandidate 的 SID 相同。
對於需要大量資源來登錄和取消登錄的驅動程式 (請參閱 SQLConnect 中,對 SQL_DTC_TRANSITION_COST 的討論),重複使用 hRequest 不需額外登錄或取消登錄。
下列資料表呈現不同案例的分數指派。
集區連線與要求之間的連線屬性比較 | 無登錄/取消登錄 | 需要額外的登錄/取消登錄 |
---|---|---|
目錄 (SQL_ATTR_CURRENT_CATALOG) 不同 | 60 | 50 |
某些連線屬性不同,但目錄相同 | 90 | 70 |
所有連線屬性都完全相符 | 100 | 80 |
順序圖表
此順序圖表呈現本主題中所述的基本共用機制。 此圖只會呈現使用 SQLDriverConnect 的機制,但 SQLConnect 案例也是類似情況。
狀態圖表
此狀態圖表呈現本主題中所述的連線資訊權杖物件。 此圖只會呈現 SQLDriverConnect 的機制,但 SQLConnect 案例也是類似情況。 由於驅動程式管理員可能必須隨時處理錯誤,因此驅動程式管理員可以針對任何狀態呼叫 SQLFreeHandle。