Resiliência de conexão no driver ODBC

Baixar driver ODBC

Para garantir que os aplicativos permaneçam conectados a um Banco de Dados SQL do Azure, o driver ODBC pode restaurar conexões ociosas.

Importante

O recurso de resiliência de conexão tem suporte em versões de servidor do Banco de Dados SQL do Microsoft Azure e do SQL Server 2014 (e posteriores).

O recurso está disponível no Windows da versão do Microsoft ODBC Driver 11 for SQL Server em diante. Ele está disponível no Linux da versão 17.2 do Microsoft ODBC Driver 17 for SQL Server em diante.

Para obter mais informações sobre a resiliência de conexão ociosa, confira o Artigo técnico – Resiliência de conexão ociosa.

Para controlar o comportamento de reconexão, o ODBC Driver para SQL Server tem duas opções:

  • Contagem de repetições de conexão.

    A contagem de repetições de reconexão controla o número de tentativas de reconexão se há uma falha de conexão. Os valores válidos variam de 0 a 255. Zero (0) significa que não haverá tentativa de reconexão. O valor padrão é uma tentativa de reconexão.

    Você pode modificar o número de repetições de conexão ao:

    • Definir ou modificar uma fonte de dados que use o ODBC Driver for SQL Server com o controle de Contagem de Repetições de Conexão.

    • Use a palavra-chave de cadeia de conexão ConnectRetryCount.

      Para recuperar o número de tentativas de conexão, use o atributo de conexão SQL_COPT_SS_CONNECT_RETRY_COUNT (somente leitura). Se um aplicativo se conectar a um servidor que não dê suporte à resiliência de conexão, SQL_COPT_SS_CONNECT_RETRY_COUNT retornará 0.

  • Intervalo de repetição de conexão.

    O intervalo de repetição de conexão especifica o número de segundos entre cada tentativa de conexão. Os valores válidos são 1 a 60. O tempo total para reconexão não pode exceder o tempo limite da conexão (SQL_ATTR_QUERY_TIMEOUT em SQLSetStmtAttr). O valor padrão é 10 segundos.

    Você pode modificar o intervalo de repetição de conexão ao:

    • Definir ou modificar uma fonte de dados que use o ODBC Driver for SQL Server com o controle de Intervalo de Repetição de Conexão.

    • Use a palavra-chave de cadeia de conexão ConnectRetryInterval.

      Para recuperar a duração do intervalo de repetição de conexão, use o atributo de conexão SQL_COPT_SS_CONNECT_RETRY_INTERVAL (somente leitura).

Se um aplicativo estabelecer uma conexão com SQL_DRIVER_COMPLETE_REQUIRED e posteriormente tentar executar uma instrução em uma conexão interrompida, o driver ODBC não exibirá a caixa de diálogo novamente. Além disso, durante a recuperação em andamento:

  • Durante a recuperação, as chamadas para SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD) precisam retornar SQL_CD_FALSE.
  • Se a recuperação falhar, as chamadas para SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD) precisarão retornar SQL_CD_TRUE.

Os seguintes códigos de estado são retornados por qualquer função que execute um comando no servidor:

Estado Mensagem
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.

Exemplo

O exemplo a seguir contém duas funções. func1 mostra como você pode se conectar com um DSN (nome da fonte de dados) que usa o ODBC Driver for SQL Server no Windows. O DSN usa a Autenticação do SQL Server e especifica a ID de usuário. Em seguida, func1 recupera o número de repetições de conexão com SQL_COPT_SS_CONNECT_RETRY_COUNT.

func2 usa SQLDriverConnect, a palavra-chave de cadeia de conexão ConnectRetryCount e atributos de conexão para recuperar a configuração de repetições de conexão e o intervalo de repetição.

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

Confira também

Microsoft ODBC Driver for SQL Server