Partilhar via


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

Aplica-se a:Banco de Dados SQL do AzureInstância Gerenciada SQL do Azure do Azure 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 Azure desloca rapidamente os recursos de hardware para equilibrar melhor a carga de várias 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 com a conexão ao seu banco de dados no Banco de dados SQL. Os aplicativos que se conectam ao seu banco de dados devem ser criados para esperar esses erros transitórios. Para manipulá-los, implemente a lógica de repetição em seu código em vez de apresentá-los aos usuários como erros de aplicativo.

Se o seu programa cliente usa ADO.NET, seu programa é informado sobre o erro transitório pelo lance 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 ligação, tente

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

  • Um erro transitório ocorre durante um comando de consulta SQL Database e SQL Managed Instance

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.

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

Os programas cliente que ocasionalmente encontram um erro transitório são mais robustos quando contêm lógica de repetição. Quando o seu programa comunica com a sua base de dados no Banco de Dados SQL através de middleware de terceiros, questione o fornecedor se o middleware possui um mecanismo de repetição para erros temporários.

Princípios para repetição

  • Se o erro for transitório, tente abrir novamente uma ligação.
  • Não repita diretamente uma instrução SELECT de um Banco de Dados SQL ou de uma Instância Gerenciada 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 UPDATE Banco de Dados SQL ou Instância Gerenciada SQL 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 tentativa

  • 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 a sua lógica de tentativa e 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 utilizador.
  • 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 nova tentativa de conexão

Se o programa cliente se conectar à sua base de dados no Azure SQL Database usando a classe .NET Framework System.Data.SqlClient.SqlConnection, use o .NET 4.6.1 ou uma versão posterior (ou .NET Core) para poder tirar partido da funcionalidade de repetição de conexão. Para obter mais informações sobre esse recurso, consulte Propriedade SqlConnection.ConnectionString.

Quando crias a cadeia de conexão para o teu objeto SqlConnection , coordena 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 é 1 a 60.
  • Tempo limite de conexão: O padrão é 15 segundos. O intervalo é 0 a 2147483647.
  • Tempo limite do comando: O padrão é 30 segundos. O intervalo é 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 da conexão inclui os seguintes tipos distintos:

  • A resiliência ao abrir conexão refere-se ao método inicial SqlConnection.Open ou OpenAsync(). A primeira tentativa de conexão é contada como tentativa zero. ConnectRetryCount se aplica a tentativas subsequentes. Portanto, se a conexão zero falhar (isso pode não ocorrer imediatamente), primeiro aplicar-se-á o intervalo de tentativas ConnectRetryInterval, seguido pelas tentativas subsequentes 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.

  • A resiliência de ligações inativas refere-se à deteção automática e reconexão de ligações inativas existentes que foram interrompidas. A primeira tentativa de reconectar uma conexão ociosa quebrada é contada como a primeira tentativa de repetição. Para aproveitar todas as tentativas de novas tentativas, o Tempo Limite do 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 --> 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 Command Timeout 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.

Observação

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 seu 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 sua consulta está a ser executada, o objeto SqlConnection não volta a tentar a operação de ligaçã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 tente novamente a operação de conexão. Se a nova tentativa for bem-sucedida, a consulta será enviada para execução.

ConnectRetryCount deve combinar-se com a lógica de repetição da aplicação

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 string de conexão para a sua base de dados a partir do portal do Azure.

Obter a cadeia de conexão do portal do Azure

Utilize o portal do Azure para obter a cadeia de conexão necessária para o seu programa cliente interagir com o Azure SQL Database.

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

  2. Digite o nome do banco de dados na caixa de texto do filtro perto do canto superior esquerdo do painel bancos de dados SQL.

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

  4. Depois que o painel for exibido 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. No painel do banco de dados, selecione Mostrar cadeias de conexão de banco de dados.

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

    Captura de tela mostrando como copiar a cadeia de conexão ADO para seu banco de dados.

  7. Edite a cadeia de conexão conforme necessário. Neste exemplo, insira sua senha na cadeia de conexão ou remova <server-name> 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. Entre no portal do Azure.

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

  3. Desloque-se e selecione SQL servers.

    Captura de ecrã de Localizar o servidor da Base de Dados SQL do Azure no portal.

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

  5. Selecione a linha do seu servidor. É apresentado um painel para o servidor.

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

  7. Selecione Firewall.

    captura de tela de Selecionar configurações > 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 fazer com que o valor baixo termine com .0 e o alto valor termine com .255.
  10. Selecione Salvar.

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 Controle.
  2. Selecione Todos os itens do Painel de Controle>Firewall do Windows>Configurações Avançadas>Regras>Ações de Saída>Nova Regra.

Se o seu programa cliente estiver hospedado numa máquina virtual (VM) do Azure, leia Portas para 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 tentativa de reabertura da conexão para o Azure SQL é feita imediatamente, melhorando assim o desempenho de aplicações compatíveis com a 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 certos erros dentro do período de tempo limite de conexão.
  • A gestão de conexões em pool é suportada, o que inclui uma verificação eficiente de que o objeto de conexão fornecido ao seu programa está a funcionar.

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 .NET para ajudar no registro. Para obter mais informações, consulte 5 - Tão fácil quanto cair de um log: Use o Logging Application Block.

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 de 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 na base 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 você 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.

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 Aplicativo de Tratamento de Falhas Transitórias.

Observação

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
  • classe ReliableSqlConnection
    • método ExecuteCommand

No espaço de nomes Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.TestSupport:

  • AlwaysTransientErrorDetectionStrategy classe
  • classe NeverTransientErrorDetectionStrategy

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 registo abstrai a funcionalidade de registo do destino de registo para que o código da aplicação seja consistente, independentemente da localização e do tipo do destino de registo.

Para obter mais informações, consulte 5 - Tão fácil como cair da cadeira: Use o "Logging Application Block".

Código fonte do método EntLib60 IsTransient

Em seguida, a partir da classe SqlDatabaseTransientErrorDetectionStrategy, está o código-fonte C# para o método IsTransient. O código-fonte esclarece quais erros foram considerados transitórios e dignos de repetição.

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