ODBC ドライバーの接続の回復性
アプリケーションが接続された状態を確実に維持するために、ODBC ドライバーでは、アイドル状態の接続を復元できます。
重要
接続の回復性機能は、Microsoft Azure SQL Database、Fabric 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」 (技術記事 - アイドル接続の回復性) をご覧ください。
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 を指定します。 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();
}