ODBC 驅動程式中的連線復原功能

下載 ODBC 驅動程式

若要確保應用程式保持連線到 Azure SQL Database,ODBC 驅動程式可以還原閒置的連線。

重要

Microsoft Azure SQL Database 與 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 會使用 SQLDriverConnectConnectRetryCount 連接字串關鍵字和連線屬性來擷取連線重試與重試間隔的設定。

// 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_for_userID;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();
}

另請參閱

Microsoft ODBC Driver for SQL Server