Compartir vía


Resistencia de conexión inactiva

Descargar controlador PHP

Resistencia de la conexión es el principio de que se puede restablecer una conexión inactiva interrumpida, con ciertas restricciones. Si se produce un error en una conexión a la base de datos, la resistencia de la conexión permite al cliente intentar volver a conectarse automáticamente. La resistencia de la conexión es una propiedad del origen de datos. Solo la admiten SQL Server 2014, y las versiones posteriores, y Azure SQL Database.

La resistencia de la conexión se implementa con dos palabras clave de conexión que se pueden agregar a las cadenas de conexión: ConnectRetryCount y ConnectRetryInterval.

Palabra clave Valores Valor predeterminado Descripción
ConnectRetryCount Un entero comprendido entre 0 y 255, ambos incluidos 1 El número máximo de intentos de restablecer una conexión interrumpida antes de abandonar. De forma predeterminada, se realiza un solo intento de restablecer una conexión cuando se interrumpe. Un valor de 0 significa que no se intentará ninguna reconexión.
ConnectRetryInterval Un entero comprendido entre 1 y 60, ambos incluidos 10 El tiempo, en segundos, entre los intentos de restablecer una conexión. La aplicación intentará volver a conectarse inmediatamente al detectar una conexión interrumpida y, a continuación, esperará ConnectRetryInterval segundos antes de volver a intentarlo. Esta palabra clave se omite si ConnectRetryCount es igual a 0.

Si el producto de ConnectRetryCount multiplicado por ConnectRetryInterval es mayor que LoginTimeout, el cliente dejará de intentar establecer la conexión una vez que se haya alcanzado LoginTimeout; de lo contrario, seguirá intentando establecer la conexión hasta que se alcance ConnectRetryCount.

Observaciones

La resistencia de la conexión se aplica cuando la conexión está inactiva. Los errores que se producen durante la ejecución de una transacción, por ejemplo, no desencadenarán intentos de reconexión (se producirá un error en ellos, al contrario de lo que cabría esperar). Las siguientes situaciones, conocidas como estados de sesión no recuperable, no desencadenarán intentos de reconexión:

  • Tablas temporales
  • Cursores globales y locales
  • Bloqueos de transacción de nivel de sesión y contexto de transacción
  • Bloqueos de aplicaciones
  • Contexto de seguridad EXECUTE AS/REVERT
  • Identificadores de automatización OLE
  • Identificadores XML preparados
  • Marcas de seguimiento

Ejemplo

El siguiente código se conecta a una base de datos y ejecuta una consulta. La conexión se interrumpe al terminar la sesión y se intenta realizar una nueva consulta mediante la conexión interrumpida. En este ejemplo se utiliza la base de datos de ejemplo AdventureWorks.

En este ejemplo, especificamos un cursor de búfer antes de interrumpir la conexión. Si no especificamos un cursor de búfer, la conexión no se restablecerá, ya que habrá un cursor del lado servidor activo. Por lo tanto, la conexión no estará inactiva cuando se interrumpa. Sin embargo, en ese caso podremos llamar a sqlsrv_free_stmt() antes de interrumpir la conexión para desocupar el cursor y esta se restablecerá correctamente.

<?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 );
?>

Resultado esperado:

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

Consulte también

Resistencia de la conexión en el controlador ODBC