ODBC 驅動程式中的連線復原功能
為了確保應用程式保持連線,ODBC 驅動程式可以還原閑置連線。
重要
Microsoft Azure SQL 資料庫、Fabric SQL 資料庫和 SQL Server 2014(及更新版本)伺服器版本支援連線恢復功能。
從具備適用於 SQL Server 的 Microsoft ODBC 驅動程式 11 的 Windows 開始可以使用此功能。 其可在適用於 SQL Server 的 Microsoft ODBC 驅動程式 17 的 Linux 17.2 版開始取用。
如需閒置連線復原功能的詳細資訊,請參閱技術文章 - 閒置連線復原功能。
為了控制重新連線的行為,適用於 SQL Server 的 ODBC 驅動程式有兩個選項:
連接重試計數。
連線重試計數可控制連線失敗時的重新連線嘗試次數。 有效值的範圍介於 0 到 255 之間。 零 (0) 表示不嘗試重新連線。 預設值是嘗試重新連接一次。
您可以在執行下列作業時修改連接重試次數:
透過連線重試計數控制項定義或修改使用適用於 SQL Server 的 ODBC 驅動程式的資料來源。
使用
ConnectRetryCount
連接字串關鍵字。若要擷取連線重試的嘗試次數,請使用
SQL_COPT_SS_CONNECT_RETRY_COUNT
(唯讀) 連線屬性。 如果應用程式連線到不支援連線復原功能的伺服器,SQL_COPT_SS_CONNECT_RETRY_COUNT
會傳回 0。
連接重試間隔。
連接重試間隔會指定每個連接重試嘗試的間隔秒數。 有效值為 1-60。 重新連線的時間總計不可超過連線逾時 (SQLSetStmtAttr 中的 SQL_ATTR_QUERY_TIMEOUT)。 預設值為 10 秒。
您可以在執行下列作業時修改連接重試間隔:
透過連線重試間隔控制項定義或修改使用適用於 SQL Server 的 ODBC 驅動程式的資料來源。
使用
ConnectRetryInterval
連接字串關鍵字。若要擷取連線重試間隔的長度,請使用
SQL_COPT_SS_CONNECT_RETRY_INTERVAL
(唯讀) 連線屬性。
如果應用程式透過 SQL_DRIVER_COMPLETE_REQUIRED 建立連線,且後續嘗試透過中斷的連線執行陳述式,ODBC 驅動程式將不會再次顯示對話方塊。 此外,在復原進行期間,
- 在復原期間,任何對
SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD)
的呼叫,都必須傳回SQL_CD_FALSE
。 - 如果復原失敗,任何對
SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD)
的呼叫,都必須傳回SQL_CD_TRUE
。
以下是在伺服器上執行命令的任何函數皆可能傳回的狀態碼:
State | 訊息 |
---|---|
IMC01 |
The connection is broken and recovery is not possible. The client driver attempted to recover the connection one or more times and all attempts failed. Increase the value of ConnectRetryCount to increase the number of recovery attempts. |
IMC02 |
The server did not acknowledge a recovery attempt, connection recovery is not possible. |
IMC03 |
The server did not preserve the exact client TDS version requested during a recovery attempt, connection recovery is not possible. |
IMC04 |
The server did not preserve the exact server major version requested during a recovery attempt, connection recovery is not possible. |
IMC05 |
The connection is broken and recovery is not possible. The connection is marked by the server as unrecoverable. No attempt was made to restore the connection. |
IMC06 |
The connection is broken and recovery is not possible. The connection is marked by the client driver as unrecoverable. No attempt was made to restore the connection. |
範例
下列範例包含兩個函數。 func1
說明如何連線使用 Windows 版適用於 SQL Server 的 ODBC 驅動程式的資料來源名稱 (DSN)。 DSN 會使用 SQL Server 驗證,而且它會指定使用者識別碼。 接著,func1
會透過 SQL_COPT_SS_CONNECT_RETRY_COUNT
擷取連線重試次數。
func2
會使用 SQLDriverConnect
、ConnectRetryCount
連接字串關鍵字和連線屬性來擷取連線重試與重試間隔的設定。
// Connection_resiliency.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <stdio.h>
#include <sqlext.h>
#include <msodbcsql.h>
void func1() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLSMALLINT i = 21;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
// Connect to data source
retcode = SQLConnect(hdbc, (SQLCHAR*)"MyDSN", SQL_NTS, (SQLCHAR*)"userID", SQL_NTS, (SQLCHAR*)"password_for_userID", SQL_NTS);
retcode = SQLGetConnectAttr(hdbc, SQL_COPT_SS_CONNECT_RETRY_COUNT, &i, SQL_IS_INTEGER, NULL);
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
void func2() {
SQLHENV henv;
SQLHDBC hdbc1;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLSMALLINT i = 21;
#define MAXBUFLEN 255
SQLCHAR ConnStrIn[MAXBUFLEN] = "DRIVER={ODBC Driver 18 for SQL Server};SERVER=server_that_supports_connection_resiliency;Encrypt=yes;UID=userID;PWD=<password>;ConnectRetryCount=2";
SQLCHAR ConnStrOut[MAXBUFLEN];
SQLSMALLINT cbConnStrOut = 0;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3_80, SQL_IS_INTEGER);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
// SQLSetConnectAttr(hdbc1, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
retcode = SQLDriverConnect(hdbc1, NULL, ConnStrIn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
}
retcode = SQLGetConnectAttr(hdbc1, SQL_COPT_SS_CONNECT_RETRY_COUNT, &i, SQL_IS_INTEGER, NULL);
retcode = SQLGetConnectAttr(hdbc1, SQL_COPT_SS_CONNECT_RETRY_INTERVAL, &i, SQL_IS_INTEGER, NULL);
}
}
}
int main() {
func1();
func2();
}