Verbindungsresilienz im ODBC-Treiber

ODBC-Treiber herunterladen

Um sicherzustellen, dass Anwendungen mit Azure SQL-Datenbank verbunden bleiben, kann der ODBC-Treiber Verbindungen im Leerlauf wiederherstellen.

Wichtig

Die Funktion für Verbindungsresilienz wird von Microsoft Azure SQL-Datenbank und den Serverversionen von SQL Server 2014 (und höher) unterstützt.

Das Feature ist unter Windows ab dem Microsoft ODBC Driver 11 for SQL Server verfügbar. Unter Linux ist es ab Version 17.2 des Microsoft ODBC Driver 17 for SQL Server verfügbar.

Weitere Informationen zur Verbindungsresilienz für Leerlaufverbindungen finden Sie unter Technischer Artikel – Verbindungsresilienz für Leerlaufverbindungen.

Um das Verhalten bei der Verbindungswiederherstellung zu steuern, bietet der ODBC-Treiber für SQL Server zwei Optionen:

  • Anzahl Verbindungsversuche.

    Die Anzahl der Verbindungswiederholungen steuert, wie oft eine Verbindungswiederherstellung bei einem Verbindungsfehler versucht wird. Gültige Werte reichen von 0 bis 255. Null (0) bedeutet, dass keine Verbindungswiederherstellung versucht wird. Der Standardwert ist ein (1) Verbindungsversuch.

    Sie können die Anzahl der Verbindungsversuche ändern, wenn Sie:

    • Eine Datenquelle definieren oder ändern, die den ODBC-Treiber für SQL Server mit ConnectionRetryCount-Kontrolle verwendet.

    • Verwenden Sie das Verbindungszeichenfolgenschlüsselwort ConnectRetryCount.

      Verwenden Sie zum Abrufen der Anzahl der Verbindungswiederherstellungsversuche das Verbindungsattribut SQL_COPT_SS_CONNECT_RETRY_COUNT (schreibgeschützt). Wenn eine Anwendung eine Verbindung mit einem Server herstellt, der keine Verbindungsresilienz unterstützt, gibt SQL_COPT_SS_CONNECT_RETRY_COUNT 0 (Null) zurück.

  • Intervall für Wiederholungen der Verbindungen

    Das Intervall der Verbindungsversuche gibt die Anzahl der Sekunden zwischen jedem Verbindungsversuch an. Gültige Werte sind 1-60. Die Gesamtdauer der Verbindungswiederherstellung darf das Verbindungstimeout (SQL_ATTR_QUERY_TIMEOUT in SQLSetStmtAttr) nicht überschreiten. Der Standardwert beträgt 10 Sekunden.

    Sie können das Intervall für Verbindungsversuche ändern, wenn Sie:

    • Definieren oder ändern Sie eine Datenquelle die den ODBC-Treiber für SQL Server mit dem Steuerelement ConnectionRetryCount verwendet.

    • Verwenden Sie das Verbindungszeichenfolgenschlüsselwort ConnectRetryInterval.

      Verwenden Sie das Verbindungsattribut SQL_COPT_SS_CONNECT_RETRY_INTERVAL (schreibgeschützt), um die Länge des Intervalls abzurufen, in dem eine Verbindungswiederherstellung versucht wurde.

Wenn eine Anwendung eine Verbindung mit SQL_DRIVER_COMPLETE_REQUIRED herstellt und später versucht, eine Anweisung für eine unterbrochene Verbindung auszuführen, zeigt der ODBC-Treiber das Dialogfeld nicht noch mal an. Darüber hinaus während der Wiederherstellung,

  • Während der Wiederherstellung muss jeder Aufruf von SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD)SQL_CD_FALSE zurückgeben.
  • Wenn die Wiederherstellung fehlschlägt, muss jeder Aufruf von SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD)SQL_CD_TRUE zurückgeben.

Die folgenden Statuscodes werden von jeder Funktion zurückgegeben, die auf dem Server einen Befehl ausführt:

Staat Nachricht
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.

Beispiel

Das folgende Beispiel enthält zwei Funktionen. func1 zeigt, wie Sie mit einem Datenquellennamen (Data Source Name, DSN), der den ODBC-Treiber für SQL Server unter Windows verwendet, eine Verbindung herstellen. Der DSN verwendet SQL Server-Authentifizierung und gibt die Benutzer-ID an. func1 ruft anschließend die Anzahl der Verbindungsversuche mit SQL_COPT_SS_CONNECT_RETRY_COUNT ab.

func2 verwendet SQLDriverConnect, das Schlüsselwort der Verbindungszeichenfolge ConnectRetryCount sowie die Verbindungsattribute, um die Einstellung für Verbindungsversuche und das Wiederholungsintervall aufzurufen.

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

Siehe auch

Microsoft ODBC-Treiber für SQL Server