Solución de problemas de errores de conexión transitorios en SQL Database e Instancia administrada de SQL

Se aplica a:Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

En este artículo se describe cómo evitar, solucionar, diagnosticar y mitigar los errores de conexión y los errores transitorios que la aplicación cliente encuentra cuando interactúa con Azure SQL Database, Instancia administrada de Azure SQL y Azure Synapse Analytics. Aprenda a configurar la lógica de reintento, generar la cadena de conexión y ajustar otros valores de conexión.

Errores transitorios

Un error transitorio tiene una causa subyacente que pronto se solucionará automáticamente. Una causa ocasional de errores transitorios se produce cuando el sistema de Azure rápidamente desplaza recursos de hardware para equilibrar mejor la carga de varias cargas de trabajo. La mayoría de estos eventos de reconfiguración se completan en menos de 60 segundos. Durante este período de tiempo de reconfiguración, es posible que tenga problemas de conexión con la base de datos de SQL Database. Las aplicaciones que se conectan a la base de datos deberían crearse de modo que contemplen esos errores transitorios. Para controlarlos, implemente una lógica de reintento en el código en lugar de mostrarlas a los usuarios como errores de aplicación.

Si su programa cliente utiliza ADO.NET, se notifican al programa los errores transitorios a través del inicio de una excepción SqlException.

Conexión frente a comandos

Vuelva a intentar la conexión de SQL Database e Instancia administrada de SQL o establézcala de nuevo, dependiendo de lo siguiente:

  • Se produce un error transitorio durante un intento de conexión

Después de un retraso de varios segundos, vuelva a intentar la conexión.

  • Se produce un error transitorio durante un comando de consulta de SQL Database Instancia administrada de SQL

No vuelva a intentarlo inmediatamente. Por el contrario, después de un retraso, establezca de nuevo la conexión. A continuación, vuelva a intentar el comando.

Lógica de reintento para errores transitorios.

Los programas cliente que encuentran ocasionalmente un error transitorio son más sólidos cuando contienen lógica de reintento. Si el programa se comunica con la base de datos de SQL Database a través de un middleware de otros fabricantes, consulte con el proveedor si el middleware contiene lógica de reintento para errores transitorios.

Principios de reintento

  • Si el error es transitorio, intente volver a abrir una conexión.
  • No vuelva a intentar directamente una instrucción SELECT de SQL Database o Instancia administrada de SQL que produjo un error transitorio. En su lugar, establezca una conexión nueva y, después, vuelva a intentar la instrucción SELECT.
  • Cuando una instrucción UPDATE de SQL Database o Instancia administrada de SQL presenta un error transitorio, establezca una conexión nueva antes de volver a intentar dicha instrucción. La lógica de reintento debe asegurar que se completó toda la transacción de base de datos o que toda la transacción se revirtió.

Otras consideraciones para el reintento

  • Un programa por lotes que se inicia automáticamente después del horario de trabajo y que se completará antes de mañana puede permitirse el transcurso de largos intervalos de tiempo entre los reintentos.
  • Un programa de la interfaz de usuario debe tener en cuenta la tendencia humana de abandonar tras una espera demasiado larga. La solución no debe ser repetir el reintento cada pocos segundos porque dicha directiva puede saturar el sistema con solicitudes.

Aumento del intervalo entre reintentos

Se recomienda que espere 5 segundos antes del primer reintento. Si se vuelve a intentar después de un retraso menor de 5 segundos, se correrá el riesgo de sobrecargar el servicio en la nube. Para cada intento siguiente, el retraso debería aumentar exponencialmente, hasta un máximo de 60 segundos.

Para obtener una explicación del período de bloqueo para clientes que usan ADO.NET, vea Agrupación de conexiones de SQL Server (ADO.NET).

También puede establecer un número máximo de reintentos antes de que el programa se cierre automáticamente.

Ejemplos de código con lógica de reintento

Algunos ejemplos de código con la lógica de reintento se encuentran disponibles en:

Probar su lógica de reintento

Para probar la lógica de reintento, debe simular o producir un error que se pueda corregir mientras aún se ejecuta el programa.

Prueba mediante la desconexión de la red

Una forma de probar la lógica de reintento es desconectar el equipo cliente de la red mientras se ejecuta el programa. El error es:

  • SqlException.Number = 11001
  • Mensaje: "Host desconocido"

Como parte del primer reintento, puede volver a conectar el equipo cliente a la red y, después, intentar conectarlo.

Para llevar a cabo esta prueba, desconecte el equipo de la red antes de iniciar el programa. El programa reconoce entonces un parámetro de tiempo de ejecución que hace que el programa:

  • Agregue temporalmente 11001 a la lista de errores para considerarlo como transitorio.
  • Intente su primera conexión como de costumbre.
  • Una vez capturado el error, quite 11001 de la lista.
  • Muestre un mensaje que indica al usuario que conecte el equipo a la red.
  • Pause la ejecución mediante el método Console.ReadLine o un cuadro de diálogo con un botón Aceptar. El usuario presiona la tecla Entrar después de que se conecte el equipo a la red.
  • Nuevo intento de conexión, se espera una realización correcta.

Realización de la prueba escribiendo mal el nombre del usuario al conectarse

El programa deliberadamente escribe mal el nombre de usuario antes del primer intento de conexión. El error es:

  • SqlException.Number = 18456
  • Mensaje: "Error de inicio de sesión para el usuario 'WRONG_MyUserName'."

Como parte del primer reintento, el programa puede corregir el error ortográfico y, a continuación, intentar conectarse.

Para llevar a cabo esta prueba, el programa reconocerá un parámetro de tiempo de ejecución que hará que el programa:

  • Agregue temporalmente 18456 a la lista de errores para considerarlo como transitorio.
  • Agregue deliberadamente 'WRONG_' al nombre de usuario.
  • Una vez capturado el error, quite 18456 de la lista.
  • Quite 'WRONG_' del nombre de usuario.
  • Nuevo intento de conexión, se espera una realización correcta.

Parámetros .NET SqlConnection para reintento de conexión

Si el programa cliente se conecta a la base de datos de Azure SQL Database mediante la clase System.Data.SqlClient.SqlConnection de .NET Framework, use .NET 4.6.1 o una versión posterior, o .NET Core, para poder utilizar la característica de reintento de conexión. Para obtener más información sobre la característica, consulte la propiedad SqlConnection.ConnectionString.

Cuando cree la cadena de conexión para su objeto SqlConnection, coordine los valores entre los parámetros siguientes:

  • ConnectRetryCount: El valor predeterminado es 1. El intervalo es de 0 a 255.
  • ConnectRetryInterval: El valor predeterminado es 10 segundos. El intervalo es de 1 a 60.
  • Connection Timeout: El valor predeterminado es 15 segundos. El intervalo es de 0 a 2147483647.
  • Tiempo de espera del comando: el valor predeterminado es de 30 segundos. El intervalo es de 0 a 2147483647.

La configuración de reintento de conexión (ConnectRetryCount y ConnectRetryInterval) se aplica a la resistencia de la conexión. La resistencia de la conexión incluye los siguientes tipos distintos:

  • La resistencia de conexión abierta hace referencia al método SqlConnection.Open u OpenAsync(). El primer intento de conexión se cuenta como intento cero. ConnectRetryCount se aplica a los reintentos posteriores. Por lo tanto, si se produce un error en la conexión cero (es posible que esto no ocurra inmediatamente), primero se aplica ConnectRetryInterval seguido de los intentos posteriores de ConnectRetryCount (y ConnectRetryInterval). Para aprovechar todos los reintentos, la propiedad Tiempo de espera de la conexión debe proporcionar tiempo para todos los intentos.

  • La resistencia de la conexión inactiva hace referencia a la detección automática y la reconexión de las conexiones inactivas existentes que se interrumpieron. El primer intento de volver a conectar una conexión inactiva interrumpida se cuenta como primer reintento. Para aprovechar todos los reintentos, el Tiempo de espera de la conexión debe proporcionar tiempo para todos los intentos.

Ejemplo: Supongamos los siguientes valores para los parámetros ConnectRetryCount y ConnectRetryInterval:

ConnectRetryCount: 3 ConnectRetryInterval: 10 segundos

Vea cómo se usan estos valores en los escenarios siguientes:

Escenario: Conexión nueva

4:10:00 - Connection.Open() - intento cero

4:10:01 - Error de conexión detectado

4:10:11 - Reintento 1 --> El primer reintento se produce después de ConnectRetryInterval

4:10:21 - Reintento 2

4:10:31 - Reintento 3

Para este escenario, los valores elegidos deben cumplir la siguiente condición:
Connection Timeout > = ConnectRetryCount * ConnectionRetryInterval

Por ejemplo, si el recuento es 3 y el intervalo es 10 segundos, un tiempo de espera de solo 29 segundos no proporcionará al sistema tiempo suficiente para su tercer y último reintento de conexión:

29 < 3 * 10

Escenario: Conexión inactiva

ConnectRetryCount: 3 ConnectRetryInterval: 10 segundos

4:10:00 - Conexión interrumpida detectada en la ejecución del comando

4:10:00 - Reintento 1 -->El primer reintento se produce inmediatamente

4:10:10 - Reintento 2

4:10:20 - Reintento 3

Esta no es la conexión inicial. Por lo tanto, no se aplica el Tiempo de espera de la conexión. Sin embargo, dado que la recuperación de la conexión se produce durante la ejecución del comando, se aplica la configuración de Tiempo de espera del comando. El valor predeterminado de Tiempo de espera del comando es de 30 segundos. Aunque la recuperación de la conexión es rápida en circunstancias normales, una interrupción intermitente puede provocar que la recuperación requiera parte del tiempo de ejecución del comando.

En este escenario, si quiere aprovechar al máximo los reintentos de recuperación de la conexión inactiva, los valores elegidos deben cumplir la condición siguiente:
Command Timeout > (ConnectRetryCount - 1) * ConnectionRetryInterval

Por ejemplo, si el recuento es 3 y el intervalo es de 10 segundos, un valor de tiempo de espera de comando inferior a 20 segundos no dará tiempo suficiente para el tercer y último reintento para conectarse: (3 - 1) * 10 = 20'

Además, tenga en cuenta que el propio comando requiere tiempo para ejecutarse tras recuperarse la conexión.

Nota

Los valores de duración que se proporcionan en estos escenarios son solo para demostración. Los tiempos de detección reales de ambos escenarios dependen de la infraestructura subyacente.

Conexión frente a comandos

Los parámetros ConnectRetryCount y ConnectRetryInterval permiten al objeto SqlConnection volver a intentar la operación de conexión sin indicarlo al programa o sin alterarlo, como una devolución de control al programa. Los reintentos pueden producirse en las situaciones siguientes:

  • Llamada al método SqlConnection.Open
  • Llamada al método SqlConnection.Execute

Hay algo muy sutil que tener en cuenta. Si se produce un error transitorio mientras su consulta se está ejecutando, el objeto SqlConnection no vuelve a intentar la operación de conexión. Sin duda, no vuelve a intentar la consulta. Sin embargo, SqlConnection comprueba muy rápidamente la conexión antes de enviar la consulta para su ejecución. Si la comprobación rápida detecta un problema de conexión, SqlConnection vuelve a intentar la operación de conexión. Si el reintento se realiza correctamente, se envía la consulta para su ejecución.

¿Se debe combinar ConnectRetryCount con lógica de reintento de la aplicación?

Supongamos que su aplicación tiene una lógica de reintento personalizada. Puede reintentar la operación de conexión cuatro veces. Si agrega ConnectRetryInterval y ConnectRetryCount = 3 a la cadena de conexión, aumentará el número de reintentos a 4 * 3 = 12 reintentos. Es posible que no desee un gran número de reintentos.

Conexiones a la base de datos en SQL Database

Conexión: Cadena de conexión

La cadena de conexión necesaria para conectarse a la base de datos es ligeramente diferente de la cadena que se utiliza para conectarse a SQL Server. Puede copiar la cadena de conexión para la base de datos en Azure Portal.

Obtenga la cadena de conexión del portal de Azure

Utilice Azure Portal para obtener la cadena de conexión necesaria para que su programa cliente interactúe con Azure SQL Database.

  1. Seleccione Todos los servicios>Bases de datos SQL.

  2. Escriba el nombre de la base de datos en el cuadro de texto de filtro situado en la esquina superior izquierda del panel Bases de datos SQL.

  3. Seleccione la fila correspondiente a la base de datos.

  4. Cuando aparezca el panel de su base de datos, para una mayor comodidad visual puede seleccionar los botones Minimizar para contraer las hojas que utilizó para examinar y filtrar la base de datos.

  5. En el panel de la base de datos, seleccione Mostrar cadenas de conexión de la base de datos.

  6. Copie la cadena de conexión adecuada. Por ejemplo, si piensa usar la biblioteca de conexiones de ADO.NET, copie la cadena adecuada de la pestaña ADO.NET.

    Copy the ADO connection string for your database

  7. Edite la cadena de conexión según sea necesario. Por ejemplo, inserte su contraseña en la cadena de conexión o quite "@<nombre del servidor>" del nombre de usuario si el nombre de servidor o el nombre de usuario es demasiado largo.

  8. En un formato u otro, pegue la información de la cadena de conexión en el código del programa cliente.

Para obtener más información, consulte Cadenas de conexión y archivos de configuración.

Conexión: Dirección IP

Debe configurar SQL Database para que acepte la comunicación desde la dirección IP del equipo que hospeda el programa cliente. Para establecer esta configuración, modifique la configuración del firewall a través de Azure Portal.

Si olvida configurar la dirección IP, el programa fallará con un mensaje de error que indica la dirección IP necesaria.

  1. Inicie sesión en Azure Portal.

  2. En la lista de la izquierda, seleccione Todos los servicios.

  3. Desplácese y seleccione Servidores SQL Server.

    Find your Azure SQL Database server in the portal

  4. En el cuadro de texto de filtro, empiece a escribir el nombre del servidor. Aparecerá su fila.

  5. Seleccione la fila para el servidor. Aparecerá un panel para el servidor.

  6. En el panel del servidor, seleccione Configuración.

  7. Seleccione Firewall.

    Select Settings > Firewall

  8. Seleccione Agregar IP de cliente. Escriba un nombre para la regla nueva en el primer cuadro de texto.

  9. Escriba los valores de dirección IP inferior y superior para el intervalo que quiere habilitar.

    • Puede resultar útil que el valor inferior termine en .0 y el valor alto en .255.
  10. Seleccione Guardar.

Para más información, vea Configuración del firewall en SQL Database.

Conexión: Puertos

Por lo general, debe asegurarse de que solo el puerto 1433 está abierto para la comunicación saliente en el equipo que hospeda el programa cliente.

Por ejemplo, cuando el programa cliente está hospedado en un equipo con Windows, puede usar Firewall de Windows en el host para abrir el puerto 1433.

  1. Abra el Panel de control.
  2. Seleccione Todos los elementos de Panel de control>Firewall de Windows>Configuración avanzada>Reglas de salida>Acción>Nueva regla.

Si el programa cliente se hospeda en una máquina virtual (VM) de Azure, lea Puertos más allá del 1433 para ADO.NET 4.5 y SQL Database.

Para obtener información general sobre la configuración de puertos y direcciones IP en la base de datos, vea Firewall de Azure SQL Database.

Conexión: ADO.NET 4.6.2 o versiones posteriores

Si el programa usa clases ADO.NET como System.Data.SqlClient.SqlConnection para conectarse a SQL Database, le recomendamos que use .NET Framework 4.6.2, o cualquier versión posterior.

A partir de ADO.NET 4.6.2

  • El intento de apertura de la conexión que se va a reintentar de inmediato para Azure SQL, lo que mejora el rendimiento de aplicaciones habilitadas para la nube.

A partir de ADO.NET 4.6.1

  • Con SQL Database, se mejora la confiabilidad si abre una conexión con el método SqlConnection.Open. Ahora, el método Open incorpora los mejores mecanismos de reintento en respuesta a errores transitorios para determinados errores dentro del período de tiempo de espera de conexión.
  • Se admite a agrupación de conexiones, que incluye una comprobación eficaz de que el objeto de conexión que ofrece el programa está funcionando.

Cuando se usa un objeto de conexión desde un grupo de conexiones, se recomienda que el programa cierre temporalmente la conexión cuando no se vaya a usar de inmediato. Volver a abrir una conexión no tiene un costo alto, pero sí lo tiene crear una nueva.

Si usa ADO.NET 4.0 o versiones anteriores, se recomienda que lo actualice a la versión de ADO.NET más reciente. Desde agosto de 2018 se puede descargar ADO.NET 4.6.2.

Diagnóstico

Diagnóstico: Probar si las utilidades pueden conectarse

Si el programa no puede conectarse a la base de datos en SQL Database, una opción de diagnóstico es intentar conectarse con una utilidad. Idealmente, la utilidad se conecta mediante la misma biblioteca que usa el programa.

En cualquier equipo con Windows, puede probar estas utilidades:

  • SQL Server Management Studio (ssms.exe), que se conecta mediante ADO.NET
  • sqlcmd.exe, que se conecta mediante ODBC

Una el programa se conecte, compruebe que funciona una breve consulta SELECT de SQL.

Diagnóstico: Comprobar los puertos abiertos

Si cree que los intentos de conexión no pueden realizarse debido a problemas en los puertos, puede ejecutar una utilidad en el equipo que le informa sobre las configuraciones de los puertos.

En Linux, las utilidades siguientes pueden resultar útiles:

  • netstat -nap
  • nmap -sS -O 127.0.0.1: Cambie el valor de ejemplo para que sea su dirección IP.

En Windows, la utilidad PortQry.exe puede resultar útil. Esta es una ejecución de ejemplo que consultó la situación del puerto en una base de datos de SQL Database y que se ejecutó en un equipo portátil:

[C:\Users\johndoe\]
>> portqry.exe -n johndoesvr9.database.windows.net -p tcp -e 1433

Querying target system called: johndoesvr9.database.windows.net

Attempting to resolve name to IP address...
Name resolved to 23.100.117.95

querying...
TCP port 1433 (ms-sql-s service): LISTENING

[C:\Users\johndoe\]
>>

Diagnóstico: Registrar los errores

A veces un problema intermitente se diagnostica mejor mediante la detección de un patrón general durante varios días o semanas.

El cliente puede ayudar al diagnóstico mediante el registro de todos los errores que encuentra. Puede correlacionar las entradas del registro con los datos de error que SQL Database registra internamente.

Enterprise Library 6 (EntLib60) ofrece clases administradas de .NET para ayudar con el registro. Para más información, vea 5 - El procedimiento más sencillo: uso del bloque de aplicación de registro.

Diagnóstico: Examinar los registros del sistema en busca de errores

Presentamos algunas instrucciones SELECT de Transact-SQL que consultan los registros de error y otra información.

Consulta de un registro Descripción
SELECT e.*
FROM sys.event_log AS e
WHERE e.database_name = 'myDbName'
AND e.event_category = 'connectivity'
AND 2 >= DateDiff
  (hour, e.end_time, GetUtcDate())
ORDER BY e.event_category,
  e.event_type, e.end_time;
La vista sys.event_log proporciona información acerca de eventos individuales, que incluye algunos que pueden causar errores transitorios o errores de conectividad.

Idealmente, puede poner en correlación los valores start_time o end_time con información acerca de cuándo ha tenido problemas su programa cliente.

Tiene que conectarse a la base de datos maestra para ejecutar esta consulta.
SELECT c.*
FROM sys.database_connection_stats AS c
WHERE c.database_name = 'myDbName'
AND 24 >= DateDiff
  (hour, c.end_time, GetUtcDate())
ORDER BY c.end_time;
La vista sys.database_connection_stats ofrece recuentos agregados de los tipos de eventos para realizar diagnósticos adicionales.

Tiene que conectarse a la base de datos maestra para ejecutar esta consulta.

Diagnóstico: Buscar eventos de problema en el registro de SQL Database

Puede buscar entradas sobre los eventos de problema en el registro de SQL Database. Pruebe la siguiente instrucción SELECT de Transact-SQL en la base de datos principal :

SELECT
   object_name
  ,CAST(f.event_data as XML).value
      ('(/event/@timestamp)[1]', 'datetime2')                      AS [timestamp]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="error"]/value)[1]', 'int')             AS [error]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="state"]/value)[1]', 'int')             AS [state]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="is_success"]/value)[1]', 'bit')        AS [is_success]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="database_name"]/value)[1]', 'sysname') AS [database_name]
FROM
  sys.fn_xe_telemetry_blob_target_read_file('el', null, null, null) AS f
WHERE
  object_name != 'login_event'  -- Login events are numerous.
  and
  '2015-06-21' < CAST(f.event_data as XML).value
        ('(/event/@timestamp)[1]', 'datetime2')
ORDER BY
  [timestamp] DESC
;

Algunas filas devueltas de sys.fn_xe_telemetry_blob_target_read_file

En el ejemplo siguiente se muestra el aspecto que podría tener una fila devuelta. Los valores nulos que se muestran no suelen ser nulos en las demás filas.

object_name                   timestamp                    error  state  is_success  database_name

database_xml_deadlock_report  2015-10-16 20:28:01.0090000  NULL   NULL   NULL        AdventureWorks

Enterprise Library 6

Enterprise Library 6 (EntLib60) es un marco de clases de .NET que ayuda a implementar a clientes sólidos de servicios en la nube, uno de los cuales es SQL Database. Para buscar temas dedicados a cada área en la que puede ayudar EntLib60 en, vea Enterprise Library 6 - April 2013 (Enterprise Library 6: abril de 2013).

La lógica de reintento para controlar los errores transitorios es un área en la que puede ayudar EntLib60. Para más información, vea 4: Perseverancia, el secreto de todos los triunfos: uso del bloque de aplicación de control de errores transitorios.

Nota:

El código fuente de EntLib60 está disponible de forma pública para descargarlo desde el Centro de descarga. Microsoft no tiene previsto realizar más actualizaciones de mantenimiento o de característica en EntLib.

Clases de EntLib60 para errores transitorios y reintentos

Las siguientes clases de EntLib60 son especialmente útiles para la lógica de reintento. Todas esas clases se encuentran en el espacio de nombres Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.

En el espacio de nombres Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling:

  • Clase RetryPolicy
    • ExecuteAction
  • ExponentialBackoff
  • SqlDatabaseTransientErrorDetectionStrategy
  • Clase ReliableSqlConnection
    • ExecuteCommand

En el espacio de nombres Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.TestSupport:

  • AlwaysTransientErrorDetectionStrategy
  • NeverTransientErrorDetectionStrategy

Estos son algunos vínculos a información sobre EntLib60:

EntLib60: El bloque de registro

  • El bloque de registro es una solución muy flexible y configurable que puede usar para lo siguiente:
    • Crear y almacenar los mensajes de registro en una amplia variedad de ubicaciones.
    • Clasificar y filtrar los mensajes.
    • Recopilar la información contextual es útil para la depuración y el seguimiento, así como para los requisitos de registro generales y de auditoría.
  • El bloque de registro abstrae la funcionalidad de registro desde el destino de registro para que el código de la aplicación sea coherente, con independencia de la ubicación y del tipo de almacén de registro de destino.

Para más información, vea 5 - El procedimiento más sencillo: uso del bloque de aplicación de registro.

Código fuente del método IsTransient de EntLib60

A continuación, en la clase SqlDatabaseTransientErrorDetectionStrategy, se encuentra el código fuente de C# para el método IsTransient. Desde abril de 2013, el código fuente explica qué errores se consideran transitorios y dignos de reintento.

public bool IsTransient(Exception ex)
{
  if (ex != null)
  {
    SqlException sqlException;
    if ((sqlException = ex as SqlException) != null)
    {
      // Enumerate through all errors found in the exception.
      foreach (SqlError err in sqlException.Errors)
      {
        switch (err.Number)
        {
            // SQL Error Code: 40501
            // The service is currently busy. Retry the request after 10 seconds.
            // Code: (reason code to be decoded).
          case ThrottlingCondition.ThrottlingErrorNumber:
            // Decode the reason code from the error message to
            // determine the grounds for throttling.
            var condition = ThrottlingCondition.FromError(err);

            // Attach the decoded values as additional attributes to
            // the original SQL exception.
            sqlException.Data[condition.ThrottlingMode.GetType().Name] =
              condition.ThrottlingMode.ToString();
            sqlException.Data[condition.GetType().Name] = condition;

            return true;

          case 10928:
          case 10929:
          case 10053:
          case 10054:
          case 10060:
          case 40197:
          case 40540:
          case 40613:
          case 40143:
          case 233:
          case 64:
            // DBNETLIB Error Code: 20
            // The instance of SQL Server you attempted to connect to
            // does not support encryption.
          case (int)ProcessNetLibErrorCode.EncryptionNotSupported:
            return true;
        }
      }
    }
    else if (ex is TimeoutException)
    {
      return true;
    }
    else
    {
      EntityException entityException;
      if ((entityException = ex as EntityException) != null)
      {
        return this.IsTransient(entityException.InnerException);
      }
    }
  }

  return false;
}

Pasos siguientes