Solucionar problemas de erros de conexão transitórios no Banco de Dados SQL e Instância Gerenciada de SQL

Aplica-se a:Banco de Dados SQL do AzureInstância Gerenciada de SQL do AzureAzure Synapse Analytics

Este artigo descreve como impedir, solucionar, diagnosticar e reduzir erros de conexão e erros transitórios que o aplicativo cliente encontra quando interage com o Banco de Dados SQL do Azure, a Instância Gerenciada de SQL do Azure e o Azure Synapse Analytics. Saiba como configurar a lógica de repetição, construir 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 chamado de falha transitória, tem uma causa subjacente que será resolvida em breve. Uma causa ocasional de erros transitórios é quando o sistema do Azure rapidamente alterna os recursos de hardware para melhor balanceamento de diversas cargas de trabalho. A maioria desses eventos de reconfiguração termina em menos de 60 segundos. Durante esse período de tempo de reconfiguração, você pode ter problemas ao se conectar ao banco de dados no Banco de Dados SQL. Aplicativos que se conectam ao banco de dados devem ser criados para esperar esses erros transitórios. Para lidar com eles, implemente a lógica de repetição no código, em vez de mostrá-los aos usuários como erros de aplicativo.

Se o programa cliente estiver usando ADO.NET, o programa será informado do erro transitório pelo lançamento de SqlException.

Conexão X comando

Tente novamente estabelecer a conexão ao Banco de Dados SQL e à Instância Gerenciada de SQL ou restabelecê-la, dependendo do seguinte:

  • Um erro transitório ocorre durante uma tentativa de conexão

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

  • Ocorre um erro transitório durante um comando de consulta do Banco de Dados SQL e da Instância Gerenciada de SQL

Não repita imediatamente o comando. Em vez disso, depois de um atraso, estabeleça a conexão novamente. Em seguida, tente novamente o comando.

Lógica de repetição para erros transitórios

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

Princípios de repetição

  • Se o erro for transitório, tente novamente abrir uma conexão.
  • Não tente outra vez diretamente uma instrução SELECT da Instância Gerenciada de SQL do Banco de Dados SQL que falhou com um erro transitório. Em vez disso, estabeleça uma conexão nova e tente novamente o comando SELECT.
  • Quando uma instrução UPDATE do Banco de Dados SQL ou da Instância Gerenciada de SQL falha 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 de banco de dados seja concluída ou que a transição inteira seja revertida.

Outras considerações sobre tentativas de repetição

  • Um programa em lote iniciado automaticamente depois do horário comercial e que termina antes da manhã pode se dar ao luxo de ser muito paciente com longos intervalos entre as tentativas de repetição.
  • Um programa de interface do usuário deve levar em consideração a tendência humana de desistir após uma longa espera. No entanto, a solução não deve ser tentada novamente em alguns segundos, porque essa política pode inundar o sistema com solicitações.

Aumento do intervalo entre tentativas de repetição

Recomendamos que você aguarde 5 segundos até a primeira tentativa. Tentar novamente após um atraso inferior a 5 segundos poderá sobrecarregar o serviço de nuvem. Para cada tentativa subsequente, o atraso deve aumentar exponencialmente, até um máximo de 60 segundos.

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

Talvez você também queira 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

Há exemplos de código com lógica de repetição disponíveis em:

Testar sua lógica de repetição

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

Testar por meio da desconexão da rede

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

  • SqlException.Number = 11001
  • Mensagem: "Este host não é conhecido"

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

Para tornar esse teste prático, desconecte o computador da rede antes de iniciar o programa. Em seguida, o programa reconhece um parâmetro de runtime que faz com que o programa:

  • Adicione temporariamente 11001 à sua lista de erros a serem considerados como transitórios.
  • Tente fazer sua primeira conexão como de costume.
  • Depois que o erro for detectado, remova 11001 da lista.
  • Exiba uma mensagem instruindo o usuário a conectar o computador à rede.
  • Pause a execução 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 se conectar novamente, esperando êxito.

Testar errando o nome de usuário ao se conectar

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

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

Como parte da primeira tentativa de repetição, o programa pode corrigir a ortografia e tentar se conectar.

Para tornar esse teste prático, o programa reconhece um parâmetro de runtime que faz com que o programa:

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

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

Se o programa cliente se conectar ao seu 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 nova tentativa de conexão. Para obter mais informações sobre esse recurso, veja Propriedade SqlConnection.ConnectionString.

Ao criar a cadeia de conexão para o objeto SqlConnection, coordene os valores dentre os seguintes parâmetros:

  • ConnectRetryCount: o padrão é 1. O intervalo é de 0 a 255.
  • ConnectRetryInterval: o padrão é de 10 segundos. O intervalo é de 1 a 60.
  • Connection Timeout: o padrão é de 15 segundos. O intervalo é de 0 a 2147483647.
  • Command Timeout: o padrão é de 30 segundos. O intervalo é de 0 a 2147483647.

As configurações de nova tentativa 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 Connection Timeout deve fornecer tempo para todas as tentativas.

  • A resiliência de conexão ociosa refere-se à detecção e reconexão automática de conexões ociosas existentes que foram interrompidas. A primeira tentativa de reconectar uma conexão ociosa interrompida é contada como a primeira tentativa de repetição. Para aproveitar todas as tentativas de repetição, a propriedade Command Timeout 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 detectada

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

4:10:21 – Tentativa 2 de repetição

4:10:31 – Tentativa 3 de repetição

Para esse cenário, os valores escolhidos devem atender à seguinte condição:
Connection Timeout > = ConnectRetryCount * ConnectionRetryInterval

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

29 < 3 * 10

Cenário: conexão ociosa

ConnectRetryCount: 3 ConnectRetryInterval: 10 segundos

4:10:00 – Conexão interrompida detectada na execução do comando

4:10:00 – Tentativa de repetição 1 – >Primeira tentativa de repetição ocorre imediatamente

4:10:10 – Tentativa de repetição 2

4:10:20 – Tentativa de repetição 3

Esta não é a conexão inicial. Portanto, o Connection Timeout não se aplica. No entanto, como a recuperação da conexão ocorre durante a execução do comando, a configuração Command Timeout se aplica. O padrão do Command Timeout é 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 tome 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 deverão atender à 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 menor que 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 após a recuperação da conexão.

Observação

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

Conexão X comando

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

  • Chamada ao método SqlConnection.Open
  • Chamada ao método SqlConnection.Execute

Mas há uma sutileza aqui. Se um erro transitório ocorrer durante a execução da consulta, o objeto SqlConnection não tentará repetir a operação de conexão. Isso certamente não repete a consulta. No entanto, SqlConnection verifica rapidamente a conexão antes de enviar a consulta para execução. Se a verificação rápida detectar um problema de conexão, SqlConnection repetirá a operação de conexão. Se a nova tentativa for bem-sucedida, a consulta será enviada para execução.

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

Suponha que seu aplicativo tenha 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 à cadeia de conexão, aumentará a contagem de repetição para 4 * 3 = 12 repetições. Talvez você não queira um número tão alto de repetições.

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 é um pouco diferente da cadeia de caracteres usada para se conectar ao SQL Server. Você pode copiar a cadeia de conexão para o seu banco de dados no Portal do Azure.

Obter a cadeia de conexão no portal do Azure

Obtenha no portal do Azure a cadeia de conexão que é necessária para o seu programa cliente interagir com o Banco de Dados SQL do Azure.

  1. Selecione Todos os serviços>Bancos de Dados SQL.

  2. Insira o nome do banco de dados na caixa de texto de filtro próximo ao canto superior esquerdo do painel de bancos de dados SQL.

  3. Selecione a linha do banco de dados.

  4. Depois que o painel aparecer para o banco de dados, por conveniência visual, selecione os botões de Minimização para recolher as folhas que você usou para navegar e filtrar o banco de dados.

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

  6. Copie a cadeia de conexão apropriada. Ou seja, se pretende utilizar 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 a senha na cadeia de conexão ou remova "@<nome do servidor>" do nome de usuário, se o nome de usuário ou do servidor for muito longo.

  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 definir essa configuração, edite as configurações do firewall por meio do Portal do Azure.

Se você se esquecer de configurar o endereço IP, o programa falhará com uma mensagem de erro prática que indica o endereço IP necessário.

  1. Entre no portal do Azure.

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

  3. Role e selecione servidores SQL.

    Find your Azure SQL Database server in the portal

  4. Na caixa de texto de filtro, comece digitando o nome do seu servidor. A linha é exibida.

  5. Selecione a linha do servidor. Um painel do servidor é exibido.

  6. No painel do seu servidor, selecione Configurações.

  7. Selecione Firewall.

    Select Settings > Firewall

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

  9. Digite os valores baixos e altos de endereços IP para o intervalo que deseja habilitar.

    • Pode ser útil ter o valor baixo terminado com 0,0 e o valor alto terminado com 0,255.
  10. Selecione Salvar.

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

Conexão: portas

Geralmente, você só precisa garantir que 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 com o Windows, você pode usar o Firewall do Windows no host para abrir a porta 1433.

  1. Abra o Painel de Controle.
  2. Selecione Todos os Itens do Painel de Controle>Firewall do Windows>Configurações Avançadas>Regras de Saída>Ações>Nova Regra.

Se o 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 de suporte sobre a configuração de portas e endereços IP no banco de dados, consulte: Firewall do Banco de Dados SQL do Azure.

Conexão: ADO.NET 4.6.2 ou posterior

Se seu programa usa classes do 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.

Iniciando com ADO.NET 4.6.2

  • A tentativa de abrir a conexão deve ser repetida imediatamente para o SQL do Azure, melhorando assim o desempenho de aplicativos habilitados para nuvem.

Iniciando com ADO.NET 4.6.1

  • Para o Banco de Dados SQL, há mais confiabilidade 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 da conexão.
  • O pool de conexão é compatível, o que inclui uma verificação eficiente se o objeto de conexão oferecido ao programa esteja funcionando.

Quando você usa um objeto de conexão de um pool de conexão, é recomendável que seu programa Feche temporariamente a conexão quando não for imediatamente em uso. Não é caro reabrir uma conexão, mas criar uma nova conexão é.

Se você estiver usando o ADO.NET 4.0 ou anterior, recomendaremos fazer upgrade para o ADO.NET mais recente. A partir de agosto de 2018, você pode baixar o ADO.NET 4.6.2.

Diagnósticos

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

Se o programa não se conectar ao banco de dados no Banco de Dados SQL, uma opção de diagnóstico será tentar se conectar usando um programa utilitário. O ideal é que o utilitário se conecte usando a mesma biblioteca que o programa.

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

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

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

Diagnóstico: verificar as portas abertas

Se suspeitar de uma falha na conexão por causa de problemas na porta, você poderá executar um utilitário no computador relatando as configurações de 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 endereço IP.

No Windows, o utilitário PortQry.exe pode ser útil. Aqui está uma execução de exemplo que consultou a situação da porta em um banco de dados no Banco de Dados SQL e que foi executada em um computador 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: registrar seus erros em log

Às vezes, um problema intermitente é mais bem diagnosticado pela detecção de um padrão geral ao longo de dias ou de semanas.

O cliente pode auxiliar em um diagnóstico ao registrar em log todos os erros encontrados. Convém correlacionar as entradas de log com os dados do erro que o próprio Banco de Dados SQL registra em log internamente.

O Enterprise Library 6 (EntLib60) oferece classes gerenciadas .NET para auxiliar no registro em log. Para obter mais informações, consulte 5 - Tão fácil quanto evitar um log: usar o bloqueio do aplicativo de registro em log.

Diagnóstico: examinar logs de erros do sistema

Aqui estão algumas instruções 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 exibição sys.event_log oferece informações sobre eventos individuais, o que inclui alguns que podem causar erros transitórios ou falhas de conectividade.

O ideal é que você possa correlacionar os valores start_time ou end_time com as informações sobre quando o programa cliente enfrentou 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 exibição sys.database_connection_stats oferece contagens agregadas dos tipos de eventos para diagnóstico adicional.

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

Diagnóstico: procurar eventos de problema no log do Banco de Dados SQL

Você pode procurar entradas sobre eventos de problemas no log do Banco de Dados SQL. Experimente a instrução SELECT Transact-SQL a seguir 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 como pode ser a aparência de uma linha retornada. Os valores nulos mostrados normalmente 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

Enterprise Library 6

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

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

Observação

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

Classes do EntLib60 para erros transitórios e tentativas de repetição

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

No namespace Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling:

  • Classe RetryPolicy
    • ExecuteAction
  • ExponentialBackoff
  • SqlDatabaseTransientErrorDetectionStrategy
  • Classe ReliableSqlConnection
    • ExecuteCommand

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

  • AlwaysTransientErrorDetectionStrategy
  • NeverTransientErrorDetectionStrategy

Estes são alguns links para informações sobre o EntLib60:

EntLib60: o bloqueio de log

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

Para obter mais informações, consulte 5 - Tão fácil quanto evitar um log: usar o bloqueio do aplicativo de registro em log.

O EntLib60 é o código-fonte do método IsTransient

Em seguida, na classe SqlDatabaseTransientErrorDetectionStrategy, está o código-fonte C# do método IsTransient. O código-fonte esclarece quais erros são considerados temporários e dignos de repetição até 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óximas etapas