Resolver problemas de erros de ligação transitórios na Base de Dados SQL e no SQL Managed Instance

Aplica-se a:Banco de Dados SQL do Azure Azure SQLManaged InstanceAzure Synapse Analytics

Este artigo descreve como prevenir, solucionar problemas, diagnosticar e mitigar erros de conexão e erros transitórios que seu aplicativo cliente encontra quando interage com o Banco de Dados SQL do Azure, a Instância Gerenciada SQL do Azure e o Azure Synapse Analytics. Saiba como configurar a lógica de repetição, criar a cadeia de conexão e ajustar outras configurações de conexão.

Erros transitórios (falhas transitórias)

Um erro transitório, também conhecido como falha transitória, tem uma causa subjacente que logo se resolve. Uma causa ocasional de erros transitórios é quando o sistema do Azure transfere rapidamente recursos de hardware para melhores cargas de trabalho de balanceamento de carga. A maioria destes eventos de reconfiguração termina em menos de 60 segundos. Durante este período de tempo de reconfiguração, poderá ter problemas com a ligação à base de dados na Base de Dados SQL. As aplicações que se ligam à base de dados devem ser criadas para esperar estes erros transitórios. Para os processar, implemente lógica de repetição no código em vez de os submeter aos utilizadores como erros de aplicações.

Se o programa cliente usa ADO.NET, o programa é informado sobre o erro transitório pelo lançamento de SqlException.

Conexão vs. comando

Tente novamente a conexão do Banco de Dados SQL e da Instância Gerenciada SQL ou estabeleça-a novamente, dependendo do seguinte:

  • Ocorre um erro transitório durante uma tentativa de ligação

Após um atraso de vários segundos, tente novamente a conexão.

  • Um erro transitório ocorre durante um comando de consulta Banco de Dados SQL e Instância Gerenciada SQL

Não tente novamente o comando imediatamente. Em vez disso, após um atraso, estabeleça novamente a conexão. Em seguida, tente novamente o comando.

Repita a lógica nos erros transitórios

Os programas do cliente que ocasionalmente se deparam com um erro transitório são mais robustos quando contêm lógica de repetição. Quando o programa se comunicar com seu banco de dados no Banco de dados SQL por meio de middleware de terceiros, pergunte ao fornecedor se o middleware contém lógica de repetição para erros transitórios.

Princípios para repetição

  • Se o erro for transitório, tente abrir novamente uma ligação.
  • Não tente novamente diretamente uma instrução do Banco de Dados SQL ou da Instância Gerenciada SELECT do SQL que falhou com um erro transitório. Em vez disso, estabeleça uma nova conexão e, em seguida, tente novamente o SELECT.
  • Quando uma instrução do Banco de Dados SQL ou da Instância Gerenciada SQL UPDATE falhar com um erro transitório, estabeleça uma nova conexão antes de tentar novamente a UPDATE. A lógica de repetição deve garantir que toda a transação do banco de dados seja concluída ou que toda a transação seja revertida.

Outras considerações para repetição

  • Um programa em lote que começa automaticamente após o horário de trabalho e termina antes da manhã pode se dar ao luxo de ser muito paciente com longos intervalos de tempo entre suas tentativas de repetição.
  • Um programa de interface do usuário deve levar em conta a tendência humana de desistir depois de muito tempo de espera. A solução não deve tentar novamente a cada poucos segundos, porque essa política pode inundar o sistema com solicitações.

Aumento do intervalo entre novas tentativas

Recomendamos que aguarde 5 segundos antes da primeira tentativa. Tentar novamente após um atraso inferior a 5 segundos corre o risco de sobrecarregar o serviço de nuvem. Para cada nova tentativa subsequente, o atraso deve crescer exponencialmente, até um máximo de 60 segundos.

Para obter uma discussão sobre o período de bloqueio para clientes que usam ADO.NET, consulte Pool de conexões (ADO.NET).

Você também pode querer definir um número máximo de novas tentativas antes que o programa seja encerrado automaticamente.

Exemplos de código com lógica de repetição

Exemplos de código com lógica de repetição estão disponíveis em:

Teste sua lógica de repetição

Para testar sua lógica de repetição, você deve simular ou causar um erro que pode ser corrigido enquanto o programa ainda está em execução.

Teste desconectando-se da rede

Uma maneira de testar sua lógica de repetição é desconectar o computador cliente da rede enquanto o programa está em execução. O erro é:

  • SqlException.Number = 11001
  • Mensagem: "Nenhum anfitrião é conhecido"

Como parte da primeira tentativa de repetição, você pode reconectar o computador cliente à rede e, em seguida, tentar se conectar.

Para tornar este teste prático, desligue o computador da rede antes de iniciar o programa. Em seguida, o programa reconhece um parâmetro de tempo de execução que faz com que o programa:

  • Adicione temporariamente 11001 à sua lista de erros a considerar como transitórios.
  • Tente sua primeira conexão como de costume.
  • Depois que o erro for detetado, remova 11001 da lista.
  • Exiba uma mensagem que diz ao usuário para conectar o computador à rede.
  • Pause a execução adicional usando o método Console.ReadLine ou uma caixa de diálogo com um botão OK. O usuário pressiona a tecla Enter depois que o computador é conectado à rede.
  • Tente novamente se conectar, esperando sucesso.

Teste digitando incorretamente o nome de usuário ao se conectar

Seu programa pode propositalmente escrever incorretamente o nome de usuário antes da primeira tentativa de conexão. O erro é:

  • SqlException.Number = 18456
  • Mensagem: "Falha de login para o usuário 'WRONG_MyUserName'."

Como parte da primeira tentativa de repetição, o programa pode corrigir o erro ortográfico e, em seguida, tentar se conectar.

Para tornar esse teste prático, seu programa reconhece um parâmetro de tempo de execução que faz com que o programa:

  • Adicione temporariamente 18456 à sua lista de erros a considerar como transitórios.
  • Adicione propositadamente 'WRONG_' ao nome de usuário.
  • Depois que o erro for detetado, remova 18456 da lista.
  • Remova 'WRONG_' do nome de usuário.
  • Tente novamente se conectar, esperando sucesso.

Parâmetros .NET SqlConnection para repetição de conexão

Se o programa cliente se conectar ao banco de dados no Banco de Dados SQL do Azure usando a classe System.Data.SqlClient.SqlConnection do .NET Framework, use o .NET 4.6.1 ou uma versão posterior (ou .NET Core) para que você possa usar seu recurso de repetição de conexão. Para obter mais informações sobre esse recurso, consulte Propriedade SqlConnection.ConnectionString.

Quando você cria a cadeia de conexão para seu objeto SqlConnection , coordene os valores entre os seguintes parâmetros:

  • ConnectRetryCount: O padrão é 1. O intervalo é de 0 a 255.
  • ConnectRetryInterval: O padrão é 10 segundos. O intervalo é de 1 a 60.
  • Tempo limite de conexão: o padrão é 15 segundos. O intervalo é de 0 a 2147483647.
  • Tempo limite do comando: o padrão é 30 segundos. O intervalo é de 0 a 2147483647.

As configurações de repetição de conexão (ConnectRetryCount e ConnectRetryInterval) aplicam-se à resiliência da conexão. A resiliência de conexão inclui os seguintes tipos distintos:

  • A resiliência de conexão aberta refere-se ao método inicial SqlConnection.Open ou OpenAsync(). A primeira tentativa de conexão é contada como tentativa zero. ConnectRetryCount aplica-se a tentativas subsequentes. Portanto, se a conexão zero falhar (isso pode não ocorrer imediatamente), ConnectRetryInterval será aplicado primeiro, seguido por tentativas subsequentes de ConnectRetryCount (e ConnectRetryInterval). Para aproveitar todas as tentativas de repetição, a propriedade Tempo Limite de Conexão deve fornecer tempo para todas as tentativas.

  • Resiliência de conexão ociosa refere-se à deteção automática e reconexão de conexões ociosas existentes que foram quebradas. A primeira tentativa de reconectar uma conexão ociosa quebrada é contada como a primeira tentativa de repetição. Para aproveitar todas as tentativas de repetição, o Tempo Limite de Comando deve fornecer tempo para todas as tentativas.

Exemplo: Suponha os seguintes valores para os parâmetros ConnectRetryCount e ConnectRetryInterval :

ConnectRetryCount: 3 ConnectRetryInterval: 10 segundos

Veja como esses valores são usados nos seguintes cenários:

Cenário: Nova conexão

4:10:00 - Connection.Open() - tentativa zero

4:10:01 - Falha de conexão detetada

4:10:11 - Repetição 1 --> A primeira tentativa ocorre após ConnectRetryInterval

4:10:21 - Repetição 2

4:10:31 - Repetição 3

Para este cenário, os valores escolhidos devem satisfazer a seguinte condição:
Connection Timeout > = ConnectRetryCount * ConnectionRetryInterval

Por exemplo, se a contagem for 3 e o intervalo for de 10 segundos, um tempo limite de apenas 29 segundos não fornecerá tempo suficiente para a terceira e última tentativa de conexão do sistema:

29 < 3 * 10

Cenário: Conexão ociosa

ConnectRetryCount: 3 ConnectRetryInterval: 10 segundos

4:10:00 - Conexão quebrada detetada na execução do comando

4:10:00 - Repetição 1 -->Primeira tentativa ocorre imediatamente

4:10:10 - Repetição 2

4:10:20 - Repetição 3

Esta não é a conexão inicial. Portanto, o Tempo Limite de Conexão não se aplica. No entanto, como a recuperação da conexão ocorre durante a execução do comando, a configuração Tempo limite do comando se aplica. O Tempo Limite de Comando padrão é de 30 segundos. Embora a recuperação da conexão seja rápida em circunstâncias típicas, uma interrupção intermitente pode fazer com que a recuperação leve parte do tempo de execução do comando.

Para esse cenário, se você quiser aproveitar ao máximo as tentativas de recuperação de conexão ociosa, os valores escolhidos devem satisfazer a seguinte condição:
Command Timeout > (ConnectRetryCount - 1) * ConnectionRetryInterval

Por exemplo, se a contagem for 3 e o intervalo for de 10 segundos, um valor de tempo limite de comando inferior a 20 segundos não daria tempo suficiente para a terceira e última tentativa de conexão: (3 - 1) * 10 = 20'

Além disso, considere que o comando em si requer tempo para ser executado depois que a conexão é recuperada.

Nota

Os valores de duração fornecidos nesses cenários são apenas para demonstração. Os tempos reais de deteção em ambos os cenários dependem da infraestrutura subjacente.

Conexão vs. comando

Os parâmetros ConnectRetryCount e ConnectRetryInterval permitem que o objeto SqlConnection tente novamente a operação de conexão sem informar ou incomodar o programa, como retornar o controle ao programa. As novas tentativas podem ocorrer nas seguintes situações:

  • Chamada de método SqlConnection.Open
  • Chamada do método SqlConnection.Execute

Há uma sutileza. Se ocorrer um erro transitório enquanto a consulta estiver sendo executada, o objeto SqlConnection não tentará novamente a operação de conexão. Ele certamente não tenta novamente sua consulta. No entanto, SqlConnection verifica rapidamente a conexão antes de enviar sua consulta para execução. Se a verificação rápida detetar um problema de conexão, SqlConnection tentará novamente a operação de conexão. Se a nova tentativa for bem-sucedida, a consulta será enviada para execução.

ConnectRetryCount deve ser combinado com a lógica de repetição do aplicativo

Suponha que seu aplicativo tenha uma lógica de repetição personalizada robusta. Ele pode repetir a operação de conexão quatro vezes. Se você adicionar ConnectRetryInterval e ConnectRetryCount =3 à sua cadeia de conexão, aumentará a contagem de tentativas para 4 * 3 = 12 tentativas. Você pode não pretender um número tão alto de tentativas.

Conexões com seu banco de dados no Banco de dados SQL

Conexão: Cadeia de conexão

A cadeia de conexão necessária para se conectar ao banco de dados é ligeiramente diferente da cadeia de caracteres usada para se conectar ao SQL Server. Você pode copiar a cadeia de conexão para seu banco de dados do portal do Azure.

Obter a cadeia de conexão do portal do Azure

Use o portal do Azure para obter a cadeia de conexão necessária para que seu programa cliente interaja com o Banco de Dados SQL do Azure.

  1. Selecione Todos os bancos de dados SQL de serviços>.

  2. Digite o nome do seu banco de dados na caixa de texto do filtro perto do canto superior esquerdo da folha Bancos de dados SQL.

  3. Selecione a linha para o seu banco de dados.

  4. Depois que a folha aparecer para seu banco de dados, para conveniência visual, selecione os botões Minimizar para recolher as lâminas usadas para navegação e filtragem de banco de dados.

  5. Na folha do banco de dados, selecione Mostrar cadeias de conexão do banco de dados.

  6. Copie a cadeia de conexão apropriada. ou seja, se você pretende usar a biblioteca de conexões ADO.NET, copie a cadeia de caracteres apropriada da guia ADO.NET .

    Copy the ADO connection string for your database

  7. Edite a cadeia de conexão conforme necessário. ou seja, insira sua senha na cadeia de conexão ou remova "@<servername>" do nome de usuário se o nome de usuário ou o nome do servidor forem muito longos.

  8. Em um formato ou outro, cole as informações da cadeia de conexão no código do programa cliente.

Para obter mais informações, consulte Cadeias de conexão e arquivos de configuração.

Conexão: Endereço IP

Você deve configurar o Banco de dados SQL para aceitar a comunicação do endereço IP do computador que hospeda o programa cliente. Para configurar essa configuração, edite as configurações de firewall por meio do portal do Azure.

Se você esquecer de configurar o endereço IP, seu programa falhará com uma mensagem de erro útil que indica o endereço IP necessário.

  1. Inicie sessão no portal do Azure.

  2. Na lista à esquerda, selecione Todos os serviços.

  3. Role e selecione SQL servers.

    Find your Azure SQL Database server in the portal

  4. Na caixa de texto do filtro, comece a digitar o nome do servidor. A sua linha é apresentada.

  5. Selecione a linha para o seu servidor. É apresentada uma folha para o servidor.

  6. Na folha do servidor, selecione Configurações.

  7. Selecione Firewall.

    Select Settings > Firewall

  8. Selecione Adicionar IP do cliente. Digite um nome para a nova regra na primeira caixa de texto.

  9. Digite os valores de endereço IP baixo e alto para o intervalo que você deseja habilitar.

    • Pode ser útil ter a extremidade de baixo valor com .0 e a extremidade de alto valor com .255.
  10. Selecione Guardar.

Para obter mais informações, consulte Definir configurações de firewall no Banco de dados SQL.

Conexão: Portas

Normalmente, você precisa garantir que apenas a porta 1433 esteja aberta para comunicação de saída no computador que hospeda o programa cliente.

Por exemplo, quando o programa cliente está hospedado em um computador Windows, você pode usar o Firewall do Windows no host para abrir a porta 1433.

  1. Abra o Painel de Controlo.
  2. Selecione Todos os itens do Painel de Controle Configurações>avançadas do>Firewall>do Windows Regras>de saída Ações>Nova regra.

Se o seu programa cliente estiver hospedado em uma máquina virtual (VM) do Azure, leia Portas além de 1433 para ADO.NET 4.5 e Banco de Dados SQL.

Para obter informações básicas sobre a configuração de portas e endereços IP em seu banco de dados, consulte Firewall do Banco de Dados SQL do Azure.

Conexão: ADO.NET 4.6.2 ou posterior

Se o seu programa usa classes ADO.NET como System.Data.SqlClient.SqlConnection para se conectar ao Banco de dados SQL, recomendamos que você use o .NET Framework versão 4.6.2 ou posterior.

Começando com ADO.NET 4.6.2

  • A conexão aberta tenta ser repetida imediatamente para o Azure SQL, melhorando assim o desempenho de aplicativos habilitados para nuvem.

Começando com ADO.NET 4.6.1

  • Para o Banco de dados SQL, a confiabilidade é melhorada quando você abre uma conexão usando o método SqlConnection.Open . O método Open agora incorpora mecanismos de repetição de melhor esforço em resposta a falhas transitórias para determinados erros dentro do período de tempo limite de conexão.
  • O pool de conexões é suportado, o que inclui uma verificação eficiente de que o objeto de conexão fornecido ao seu programa está funcionando.

Quando você usa um objeto de conexão de um pool de conexões, recomendamos que o programa feche temporariamente a conexão quando ela não estiver em uso imediatamente. Não é caro reabrir uma conexão, mas é criar uma nova conexão.

Se você usa o ADO.NET 4.0 ou anterior, recomendamos que atualize para o ADO.NET mais recente. A partir de agosto de 2018, você pode baixar ADO.NET 4.6.2.

Diagnóstico

Diagnóstico: Teste se os utilitários podem se conectar

Se o programa não conseguir se conectar ao banco de dados no Banco de dados SQL, uma opção de diagnóstico é tentar se conectar a um programa utilitário. Idealmente, o utilitário se conecta usando a mesma biblioteca que o programa usa.

Em qualquer computador Windows, você pode tentar estes utilitários:

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

Depois que o programa estiver conectado, teste se uma consulta SQL SELECT curta funciona.

Diagnóstico: Verifique as portas abertas

Se suspeitar que as tentativas de ligação falham devido a problemas de porta, pode executar um utilitário no computador que informa sobre as configurações da porta.

No Linux, os seguintes utilitários podem ser úteis:

  • netstat -nap
  • nmap -sS -O 127.0.0.1: Altere o valor de exemplo para ser o seu endereço IP.

No Windows, o utilitário PortQry.exe pode ser útil. Aqui está um exemplo de execução que consultou a situação da porta em um banco de dados no Banco de dados SQL e que foi executado em um laptop:

[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: Registre seus erros

Um problema intermitente às vezes é melhor diagnosticado pela deteção de um padrão geral ao longo de dias ou semanas.

Seu cliente pode ajudar em um diagnóstico, registrando todos os erros encontrados. Talvez seja possível correlacionar as entradas de log com dados de erro que o próprio Banco de dados SQL registra internamente.

A Enterprise Library 6 (EntLib60) oferece classes gerenciadas pelo .NET para ajudar no registro em log. Para obter mais informações, consulte 5 - Tão fácil quanto cair de um log: Use o bloco de aplicativos de log.

Diagnóstico: Examine os logs do sistema em busca de erros

Aqui estão algumas instruções Transact-SQL SELECT que consultam logs de erros e outras informações.

Consulta de log Descrição
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;
A visualização sys.event_log oferece informações sobre eventos individuais, o que inclui alguns que podem causar erros transitórios ou falhas de conectividade.

Idealmente, você pode correlacionar os valores start_time ou end_time com informações sobre quando o programa cliente teve problemas.

Você deve se conectar ao banco de dados mestre para executar essa 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;
A visualização sys.database_connection_stats oferece contagens agregadas de tipos de eventos para diagnósticos adicionais.

Você deve se conectar ao banco de dados mestre para executar essa consulta.

Diagnóstico: Pesquisar eventos de problema no log do Banco de dados SQL

Você pode pesquisar entradas sobre eventos problemáticos no log do Banco de dados SQL. Tente a seguinte instrução Transact-SQL SELECT no banco de dados mestre :

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
;

Algumas linhas retornadas de sys.fn_xe_telemetry_blob_target_read_file

O exemplo a seguir mostra a aparência de uma linha retornada. Os valores nulos mostrados geralmente não são nulos em outras linhas.

object_name                   timestamp                    error  state  is_success  database_name

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

Biblioteca Empresarial 6

Enterprise Library 6 (EntLib60) é uma estrutura de classes .NET que ajuda a implementar clientes robustos de serviços de nuvem, um dos quais é o Banco de dados SQL. Para localizar tópicos dedicados a cada área na qual o EntLib60 pode ajudar, consulte Enterprise Library 6 - April 2013.

A lógica de repetição para lidar com erros transitórios é uma área na qual o EntLib60 pode ajudar. Para obter mais informações, consulte 4 - Perseverança, segredo de todos os triunfos: Use o bloco de aplicativos de tratamento de falhas transitórias.

Nota

O código-fonte do EntLib60 está disponível para download público no Centro de Download. A Microsoft não tem planos de fazer mais atualizações de recursos ou atualizações de manutenção para o EntLib.

Classes EntLib60 para erros transitórios e novas tentativas

As seguintes classes EntLib60 são particularmente úteis para lógica de repetição. Todas essas classes são encontradas em ou sob o namespace Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.

No namespace Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling:

  • Classe RetryPolicy
    • Método ExecuteAction
  • Classe ExponentialBackoff
  • SqlDatabaseTransientErrorDetectionStrategy classe
  • ReliableSqlConnection classe
    • Método ExecuteCommand

No namespace Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.TestSupport:

  • AlwaysTransientErrorDetectionStrategy classe
  • NeverTransientErrorDetectionStrategy classe

Aqui estão alguns links para informações sobre EntLib60:

EntLib60: O bloco de registro em log

  • O bloco de registro é uma solução altamente flexível e configurável que você pode usar para:
    • Crie e armazene mensagens de log em uma ampla variedade de locais.
    • Categorize e filtre mensagens.
    • Colete informações contextuais que sejam úteis para depuração e rastreamento, bem como para auditoria e requisitos gerais de registro.
  • O bloco de log abstrai a funcionalidade de log do destino do log para que o código do aplicativo seja consistente, independentemente do local e do tipo do armazenamento de log de destino.

Para obter mais informações, consulte 5 - Tão fácil quanto cair de um log: Use o bloco de aplicativos de log.

Código fonte do método EntLib60 IsTransient

Em seguida, da classe SqlDatabaseTransientErrorDetectionStrategy , é o código-fonte C# para o método IsTransient . O código-fonte esclarece quais erros foram considerados transitórios e dignos de nova tentativa, a partir de abril de 2013.

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;
}

Próximos passos