微软ODBC服务器驱动,Windows ODBC 驱动程序中的连接弹性

本文详细解释了Windows上的ODBC Driver for SQL Server如何通过连接重试计数和间隔来增强与Azure SQL数据库的连接弹性。了解如何配置这些参数,以及在不同情况下的应用实例。

Windows ODBC 驱动程序中的连接弹性

09/01/2020

本文内容

为了确保应用程序能与 Azure SQL 数据库 保持连接,Windows 上的 ODBC 驱动程序可以还原空闲连接。

重要

Microsoft Azure SQL 数据库和 SQL Server 2014(及更高版本)服务器版本支持连接复原能力功能。

若要详细了解空闲连接复原,请参阅技术文章 - 空闲连接复原。

为控制重新连接行为,Windows 上 的 ODBC Driver for SQL Server 有以下两个选项:

连接重试计数。

连接重试计数可在发生连接失败时,控制重新连接尝试的次数。 有效值范围为 0 到 255。 零 (0) 表示不尝试重新连接。 默认值为一次重新连接尝试。

在以下情况下可以修改连接重试次数:

定义或修改一个将 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********。

在服务器上执行命令的任何函数都会返回以下状态代码:

状态

Message

IMC01

连接已断开,且不能恢复。 客户端驱动程序尝试一次或多次恢复连接,但所有尝试均失败。 增大 ConnectRetryCount 的值以增加恢复尝试的次数。

IMC02

服务器未收到恢复尝试,无法恢复连接。

IMC03

服务器未保留恢复尝试过程中请求的确切客户端 TDS 版本,无法恢复连接。

IMC04

服务器未保留恢复尝试过程中请求的确切服务器主要版本,无法恢复连接。

IMC05

连接已断开,且不能恢复。 服务器将连接标记为不可恢复。 未尝试还原连接。

IMC06

连接已断开,且不能恢复。 客户端驱动程序将连接标记为不可恢复。 未尝试还原连接。

示例

以下示例包含两个函数。 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

#include

#include

#include

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 17 for SQL Server};SERVER=server_that_supports_connection_resiliency;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();

}

另请参阅

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值