Resilienz von Verbindungen im Leerlauf

PHP-Treiber herunterladen

Die Verbindungsresilienz beschreibt das Prinzip, dass eine unterbrochene Leerlaufverbindung mit bestimmten Einschränkungen wiederhergestellt werden kann. Wenn eine Verbindung mit der Datenbank unterbrochen wird, ermöglicht die Verbindungsresilienz es dem Client, automatisch zu versuchen, die Verbindung wiederherzustellen. Verbindungsresilienz ist eine Eigenschaft der Datenquelle. Nur SQL Server 2014 und höher und Azure SQL-Datenbank unterstützen sie.

Die Verbindungsresilienz wird mit zwei Verbindungsschlüsselwörtern implementiert, die zu Verbindungszeichenfolgen hinzugefügt werden können: ConnectRetryCount und ConnectRetryInterval.

Schlüsselwort Werte Standard Beschreibung
ConnectRetryCount Ganze Zahl von 0 bis 255 1 Die maximale Anzahl von Versuchen zum Wiederherstellen einer unterbrochenen Verbindung, bevor aufgegeben wird. Standardmäßig wird nur ein Versuch unternommen, eine Verbindung nach einer Unterbrechung wiederherzustellen. Der Wert 0 bedeutet, dass kein Wiederherstellungsversuch unternommen wird.
ConnectRetryInterval Ganze Zahl von 1 bis 60 10 Die Zeit in Sekunden zwischen den Versuchen zum Wiederherstellen einer Verbindung. Die Anwendung versucht sofort nach dem Erkennen einer unterbrochenen Verbindung, diese wiederherzustellen, und wartet dann die mit ConnectRetryInterval angegebene Anzahl von Sekunden, bevor sie es erneut versucht. Dieses Schlüsselwort wird ignoriert, wenn ConnectRetryCount gleich 0 ist.

Wenn das Produkt von ConnectRetryCount multipliziert mit ConnectRetryInterval größer als LoginTimeout ist, versucht der Client nicht mehr, eine Verbindung herzustellen, sobald LoginTimeout erreicht wird. Andernfalls versucht er weiterhin, die Verbindung wiederherzustellen, bis ConnectRetryCount erreicht wird.

Bemerkungen

Die Verbindungsresilienz gilt auch, wenn eine Verbindung sich im Leerlauf befindet. Fehler, die während der Ausführung einer Transaktion auftreten, lösen beispielsweise keine Versuche aus, die Verbindung wiederherzustellen. Bei all diesen Versuchen tritt ein Fehler auf, wie ansonsten erwartet würde. In den folgenden Situationen, die als nicht wiederherstellbare Sitzungszustände bezeichnet werden, werden keine Versuche ausgelöst, die Verbindung wiederherzustellen:

  • Temporäre Tabellen
  • Globale und lokale Cursor
  • Transaktionskontext und Transaktionssperren auf Sitzungsebene
  • Anwendungssperren
  • EXECUTE AS/REVERT-Sicherheitskontext
  • OLE-Automatisierungshandles
  • Vorbereitete XML-Handles
  • Ablaufverfolgungsflags

Beispiel

Der folgende Code stellt eine Verbindung mit einer Datenbank her und führt eine Abfrage aus. Die Verbindung wird durch Beendigung der Sitzung unterbrochen, und es wird versucht, über die unterbrochene Verbindung eine neue Abfrage zu senden. In diesem Beispiel wird die AdventureWorks-Beispieldatenbank verwendet.

In diesem Beispiel geben wir einen gepufferten Cursor an, bevor die Verbindung unterbrochen wird. Ohne die Angabe eines gepufferten Cursors würde die Verbindung nicht wiederhergestellt, weil ein aktiver serverseitiger Cursor vorhanden wäre. Daher befände sich die Verbindung zum Zeitpunkt der Unterbrechung nicht im Leerlauf. In diesem Fall könnten Sie jedoch sqlsrv_free_stmt() aufrufen, bevor die Verbindung unterbrochen wird, um den Cursor freizugeben. Dann würde die Verbindung erfolgreich wiederhergestellt.

<?php
// This function breaks the connection by determining its session ID and killing it.
// A separate connection is used to break the main connection because a session
// cannot kill itself. The sleep() function ensures enough time has passed for KILL
// to finish ending the session.
function BreakConnection( $conn, $conn_break )
{
    $stmt1 = sqlsrv_query( $conn, "SELECT @@SPID" );
    if ( sqlsrv_fetch( $stmt1 ) )
    {
        $spid=sqlsrv_get_field( $stmt1, 0 );
    }

    $stmt2 = sqlsrv_prepare( $conn_break, "KILL ".$spid );
    sqlsrv_execute( $stmt2 );
    sleep(1);
}

// Connect to the local server using Windows authentication and specify
// AdventureWorks as the database in use. Specify values for
// ConnectRetryCount and ConnectRetryInterval as well.
$databaseName = 'AdventureWorks2022';
$serverName = '(local)';
$connectionInfo = array( "Database"=>$databaseName, "ConnectRetryCount"=>10, "ConnectRetryInterval"=>10 );

$conn = sqlsrv_connect( $serverName, $connectionInfo );
if( $conn === false)  
{  
     echo "Could not connect.\n";  
     die( print_r( sqlsrv_errors(), true));  
}

// A separate connection that will be used to break the main connection $conn
$conn_break = sqlsrv_connect( $serverName, array( "Database"=>$databaseName) );

// Create a statement to retrieve the contents of a table
$stmt1 = sqlsrv_query( $conn, "SELECT * FROM HumanResources.Employee",
                       array(), array( "Scrollable"=>"buffered" ) );
if( $stmt1 === false )
{
     echo "Error in statement 1.\n";
     die( print_r( sqlsrv_errors(), true ));
}
else
{
    echo "Statement 1 successful.\n";
    $rowcount = sqlsrv_num_rows( $stmt1 );
    echo $rowcount." rows in result set.\n";
}

// Now break the connection $conn
BreakConnection( $conn, $conn_break );

// Create another statement. The connection will be reestablished.
$stmt2 = sqlsrv_query( $conn, "SELECT * FROM HumanResources.Department",
                       array(), array( "Scrollable"=>"buffered" ) );
if( $stmt2 === false )
{
     echo "Error in statement 2.\n";
     die( print_r( sqlsrv_errors(), true ));
}
else
{
    echo "Statement 2 successful.\n";
    $rowcount = sqlsrv_num_rows( $stmt2 );
    echo $rowcount." rows in result set.\n";
}

sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
?>

Erwartete Ausgabe:

Statement 1 successful.
290 rows in result set.
Statement 2 successful.
16 rows in result set.

Siehe auch

Verbindungsresilienz im ODBC-Treiber