Resiliência de conexão no 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 retornarSQL_CD_FALSE
. - Se a recuperação falhar, as chamadas para
SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD)
precisarão retornarSQL_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();
}