다음을 통해 공유


ODBC 드라이버의 연결 복원력

ODBC 드라이버 다운로드

응용 프로그램이 Azure SQL 데이터베이스와의 연결 상태를 유지하도록, ODBC 드라이버에서 유휴 연결을 복원할 수 있습니다.

Important

연결 복원력 기능은 Microsoft Azure SQL Database 및 SQL Server 2014 이상 서버 버전에서 지원됩니다.

이 기능은 Microsoft ODBC Driver 11 for SQL Server부터 Windows에서 사용할 수 있습니다. Linux에서는 Microsoft ODBC Driver 17 for SQL Server의 버전 17.2부터 사용할 수 있습니다.

유휴 연결 복원력에 대한 자세한 내용은 기술 문서 - 유휴 연결 복원력을 참조하세요.

재연결 동작을 제어하기 위해 ODBC Driver for SQL Server에는 다음과 같은 두 가지 옵션이 있습니다.

  • 연결 다시 시도 횟수.

    연결 다시 시도 횟수는 연결 오류가 있는 경우 다시 연결을 시도할 횟수를 제어합니다. 유효한 값은 0에서 255 사이입니다. 값이 0이면 다시 연결을 시도하지 않습니다. 기본값은 재연결 시도 한 번입니다.

    다음과 같이 연결 다시 시도 횟수를 수정할 수 있습니다.

    • 연결 다시 시도 횟수 제어로 ODBC Driver for SQL Server를 사용하는 데이터 원본을 정의하거나 수정합니다.

    • ConnectRetryCount 연결 문자열 키워드(keyword)를 사용합니다.

      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 연결 문자열 키워드(keyword)를 사용합니다.

      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 기반 ODBC Driver for SQL Server를 사용하는 DSN(데이터 원본 이름)과 연결할 수 있는 방법을 보여 줍니다. DSN은 SQL Server 인증을 사용하며 사용자 ID를 지정합니다. 그런 다음 func1SQL_COPT_SS_CONNECT_RETRY_COUNT를 사용하여 연결 다시 시도 횟수를 검색합니다.

func2는 연결 다시 시도 및 다시 시도 간격에 대한 설정을 검색하기 위해 SQLDriverConnect, ConnectRetryCount 연결 문자열 키워드(keyword), 연결 속성을 사용합니다.

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