ODBC ドライバーの接続の回復性

ODBC ドライバーのダウンロード

アプリケーションが Azure SQL データベースに接続されたままにするため、Windows 上の ODBC ドライバーは、アイドル状態の接続を復元できます。

重要

接続の復元機能は Microsoft Azure SQL Database と SQL Server 2014 (以降) サーバー バージョンでご利用いただけます。

この機能は、Microsoft ODBC Driver 11 for SQL Server 以降の Windows で使用できます。 Linux では、バージョン 17.2 以降の Microsoft ODBC Driver 17 for SQL Server で使用できます。

アイドル接続の回復性について詳しくは、「Technical Article - Idle Connection Resiliency」 (技術記事 - アイドル接続の回復性) をご覧ください。

再接続の動作を制御するために、Windows 上の ODBC Driver for SQL Server には 2 つの方法があります。

  • 接続の再試行回数。

    接続の再試行回数は、接続に障害が発生した場合の再接続試行回数を決定します。 有効な値の範囲は 0 ~ 255 です。 ゼロ (0) の場合、再接続は試行されません。 既定の再接続試行数は 1 です。

    次の場合に接続再試行回数を変更できます。

    • 接続の再試行回数制御を使用して、ODBC Driver for SQL Server を使用するデータ ソースを定義または変更する。

    • ConnectRetryCount の接続文字列キーワードを使用する。

      接続の再試行回数を取得するには、SQL_COPT_SS_CONNECT_RETRY_COUNT (読み取り専用) 接続属性を使用します。 アプリケーションが接続の回復性をサポートしていないサーバーに接続する場合、SQL_COPT_SS_CONNECT_RETRY_COUNT は 0 を返します。

  • 接続の再試行間隔。

    接続の再試行間隔では、接続再試行間の秒数が指定されます。 有効な値は 1 から 60 までです。 再接続の合計時間は接続タイムアウトを超過できません (SQLSetStmtAttr の SQL_ATTR_QUERY_TIMEOUT)。 既定値は 10 秒です。

    次の場合に接続再試行間隔を変更できます。

    • 接続の再試行間隔制御を使用して、ODBC Driver for SQL Server を使用するデータ ソースを定義または変更する。

    • 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.

次の例には、2 つの関数が含まれています。 func1 は、Windows 上の ODBC Driver for SQL Server を使用するデータ ソース名 (DSN) と接続する方法を示しています。 DSN は SQL Server 認証を使用し、ユーザー ID を指定します。 func1SQL_COPT_SS_CONNECT_RETRY_COUNT で接続再試行回数を取得します。

func2SQLDriverConnectConnectRetryCount の接続文字列キーワード、接続属性を使用し、接続再試行と再試行間隔の設定を取得します。

// 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