Paso 4: Conexión resistente a SQL con PHP
El programa de demostración está diseñado para que un error transitorio producido durante un intento de conexión provoque un reintento. (Los códigos de error transitorios comienzan con el prefijo "08", como se muestra en este apéndice). Pero un error transitorio durante el comando de consulta hace que el programa descarte la conexión y cree una nueva conexión, antes de reintentar el comando de consulta. No se recomienda esta opción de diseño. El programa de demostración muestra la flexibilidad del diseño que se encuentra disponible.
La longitud de este ejemplo de código se debe principalmente a la lógica de excepción catch.
La función sqlsrv_query() puede usarse para recuperar un conjunto de resultados de una consulta realizada a la SQL Database. Esta función acepta cualquier consulta y objeto de conexión y devuelve un conjunto de resultados que se puede iterar mediante el uso de sqlsrv_fetch_array().
<?php
// Variables to tune the retry logic.
$connectionTimeoutSeconds = 30; // Default of 15 seconds is too short over the Internet, sometimes.
$maxCountTriesConnectAndQuery = 3; // You can adjust the various retry count values.
$secondsBetweenRetries = 4; // Simple retry strategy.
$errNo = 0;
$serverName = "tcp:yourdatabase.database.windows.net,1433";
$connectionOptions = array("Database"=>"AdventureWorks",
"Uid"=>"yourusername", "PWD"=>"yourpassword", "LoginTimeout" => $connectionTimeoutSeconds);
$conn = null;
$arrayOfTransientErrors = array('08001', '08002', '08003', '08004', '08007', '08S01');
for ($cc = 1; $cc <= $maxCountTriesConnectAndQuery; $cc++) {
// [A.2] Connect, which proceeds to issue a query command.
$conn = sqlsrv_connect($serverName, $connectionOptions);
if ($conn === true) {
echo "Connection was established";
echo "<br>";
$tsql = "SELECT Name FROM Production.ProductCategory";
$stmt = sqlsrv_query($conn, $tsql);
if ($stmt === false) {
echo "Error in query execution";
echo "<br>";
die(print_r(sqlsrv_errors(), true));
}
while($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo $row['Name'] . "<br/>" ;
}
sqlsrv_free_stmt($stmt);
sqlsrv_close( $conn);
break;
} else {
// [A.4] Check whether the error code is on the list of allowed transients.
$isTransientError = false;
$errorCode = '';
if (($errors = sqlsrv_errors()) != null) {
foreach ($errors as $error) {
$errorCode = $error['code'];
$isTransientError = in_array($errorCode, $arrayOfTransientErrors);
if ($isTransientError) {
break;
}
}
}
if (!$isTransientError) {
// it is a static persistent error...
echo("Persistent error suffered with error code = $errorCode. Program will terminate.");
echo "<br>";
// [A.5] Either the connection attempt or the query command attempt suffered a persistent error condition.
// Break the loop, let the hopeless program end.
exit(0);
}
// [A.6] It is a transient error from an attempt to issue a query command.
// So let this method reloop and try again. However, we recommend that the new query
// attempt should start at the beginning and establish a new connection.
if ($cc >= $maxCountTriesConnectAndQuery) {
echo "Transient errors suffered in too many retries - $cc. Program will terminate.";
echo "<br>";
exit(0);
}
echo("Transient error encountered with error code = $errorCode. Program might retry by itself.");
echo "<br>";
echo "$cc attempts so far. Might retry.";
echo "<br>";
// A very simple retry strategy, a brief pause before looping.
sleep(1*$secondsBetweenRetries);
}
// [A.3] All has gone well, so let the program end.
}
?>