Provedores de lógica de repetição integrados ao SqlClient

Aplica-se a: .NET Framework .NET .NET Standard

Baixar ADO.NET

Microsoft.Data.SqlClient.SqlConfigurableRetryFactory cria provedores para cronogramas de tentativa de reexecução comuns. A lógica de repetição configurável fica desabilitada por padrão. Atribua um provedor para SqlConnection.RetryLogicProvider ou SqlCommand.RetryLogicProvider para habilitá-lo para esse objeto.

Escolha um provedor de nova tentativa

Método de fábrica Padrão de atraso
SqlConfigurableRetryFactory.CreateFixedRetryProvider Aproximadamente o mesmo atraso antes de cada tentativa novamente.
SqlConfigurableRetryFactory.CreateIncrementalRetryProvider Adiciona DeltaTime ao atraso após cada nova tentativa.
SqlConfigurableRetryFactory.CreateExponentialRetryProvider Aumenta o atraso exponencialmente após cada tentativa novamente.
SqlConfigurableRetryFactory.CreateNoneRetryProvider Não tenta de novo. Esse provedor é o padrão.

Os provedores fixo, incremental e exponencial adicionam jitter aleatório a cada intervalo. O jitter reduz rajadas sincronizadas de novas tentativas quando muitos clientes enfrentam a mesma interrupção.

NumberOfTries é o número total de tentativas, incluindo a operação inicial. Por exemplo, NumberOfTries = 3 permite a tentativa inicial e até duas tentativas. Seu alcance válido é de 1 a 60.

Lista de erros transitórios embutida

Quando SqlRetryLogicOption.TransientErrors é null, os provedores embutidos tentam novamente os 20 números de erro em SqlConfigurableRetryFactory.BaselineTransientErrors, agrupados por onde a falha se origina:

Área de falha Números de erro
Transporte do processo de login 233, 997, 10060
Disponibilidade do banco de dados durante o login 4060, 4221
Nível de declaração 1204, 1205, 1222
Limite de recursos ou limitação de taxa (throttling) 10928, 10929, 40501, 49918, 49919, 49920
Failover do serviço SQL do Azure 40143, 40197, 40540, 40613
Estado do pool de SQL dedicado 42108, 42109

Cada erro é descrito nas seções seguintes.

Importante

A configuração TransientErrors substitui a lista embutida. Não adiciona ao final da lista. Inclua todos os erros que o provedor deve tentar novamente.

No Microsoft.Data.SqlClient 7.0, SqlConfigurableRetryFactory.BaselineTransientErrors expõe a lista interna como uma coleção somente de leitura. Use-o para estender a linha de base sem copiar números de erro da fonte do driver:

var transientErrors = SqlConfigurableRetryFactory.BaselineTransientErrors
    .Append(12345)
    .ToArray();

var options = new SqlRetryLogicOption
{
    NumberOfTries = 5,
    DeltaTime = TimeSpan.FromSeconds(2),
    MaxTimeInterval = TimeSpan.FromSeconds(30),
    TransientErrors = transientErrors,
};

Para versões anteriores de drivers, crie uma coleção própria do aplicativo que contenha os erros básicos necessários e seus erros adicionais. Antes de copiar uma linha base, selecione a tag de origem SqlClient que corresponde à versão do seu pacote instalado e inspecione SqlConfigurableRetryFactory.cs. A lista no branch main pode mudar após o lançamento do seu pacote.

Erros durante o estabelecimento da conexão

Os erros a seguir podem ser tentados novamente (estão na lista integrada) ou vale a pena adicioná-los a TransientErrors acima da lista integrada.

Os seguintes erros podem ser transitórios quando ocorrem durante o estabelecimento da conexão ou ao enviar uma solicitação para o servidor. Tente novamente em uma retirada curta e limitada. Erros que persistem além de algumas tentativas geralmente indicam um problema de configuração, como servidor errado, permissões faltando, configurações de criptografia incompatíveis ou cota esgotada, que a tentativa não vai corrigir.

Erro Tipo de falha Message Troubleshooting
64 Transporte durante o login A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) A conexão TCP é interrompida durante o handshake. Não é uma falha de credenciais. Se persistir, verifique se há instabilidade de rede do lado do cliente ou um dispositivo intermediário que descarta conexões semi-estabelecidas.
233 Transporte antes do login ou TLS The client was unable to establish a connection because of an error during connection initialization process before login. O servidor geralmente retorna esse erro quando não consegue aceitar a conexão devido ao esgotamento de recursos, limite de conexão ou um cliente não suportado. Não é uma falha de credenciais. Verifique a integridade do servidor e verifique o tempo limite de logon do cliente, as configurações do TLS e a compatibilidade de versão do TLS cliente/servidor.
4060 Disponibilidade ou acesso ao banco de dados Cannot open database "%.*ls" requested by the login. The login failed. O logon é autenticado, mas não pode abrir o banco de dados solicitado. As causas transitórias incluem o fato de o banco de dados estar em transição (failover, restauração, redimensionamento) ou em pausa automática. As causas persistentes (o banco de dados não existe, o logon não tem acesso) não serão corrigidas por repetição; verifique o nome do banco de dados, o mapeamento de logon e o estado do banco de dados.
4221 Transição secundária legível Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. A réplica não está disponível para logon porque as versões de linha estão ausentes para as transações que estavam disponibilizadas em versão piloto quando a réplica foi reciclada. Reverta ou confirme as transações ativas na primária para resolver o problema. Mitigue evitando transações longas de gravação no servidor primário.
10053 Interrupção de transporte local A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.) O lado local aborta a conexão. Verifique a integridade da rede do lado do cliente e qualquer firewall local ou cliente VPN.
10054 Redefinição remota de transporte A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) O lado remoto envia uma redefinição de TCP. Causas comuns: o processo par falhou, um firewall injetou uma redefinição ou o gateway do SQL do Azure fechou uma conexão ociosa. Para padrões de redefinição por inatividade, habilite o keepalive TCP no cliente ou reduza o tempo limite de inatividade do pool de conexões.
10060 Tempo de espera da conexão esgotado A connection attempt failed because the connected party did not properly respond after a period of time. O servidor ou um dispositivo de rede intermediário não atendia antes do tempo limite da conexão TCP. Verifique a saúde do servidor, roteamento, regras do firewall e se o host e a porta configurados são acessíveis.
10928 Limite de recursos do banco de dados Resource ID: %d. The %s limit for the database is %d and has been reached. O banco de dados excede um limite de governança de recursos SQL do Azure. A ID do recurso 1 indica o limite de trabalho; A ID do recurso 2 indica o limite da sessão. Identifique o tipo de limite na mensagem e, em seguida, reduza a concorrência, aumente a capacidade do banco de dados ou encurte as operações de longa duração que mantêm o recurso ocupado.
10929 Limitação de taxa do banco de dados Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. O banco de dados está acima de sua garantia mínima e o servidor subjacente está limitando. Normalmente, a repetição é bem-sucedida quando a carga do vizinho cai. Ocorrências sustentadas indicam que você precisa de uma camada de serviço mais alta ou um ambiente menos barulhento.
40020, 40143, 40166, 40540 Subcódigo de failover do SQL do Azure Relatado no slot Error code %d do erro 40197 durante o failover. Subcódigos incorporados em uma mensagem de failover 40197 que alguns caminhos apresentam como o número de erro de nível superior. Trate-os da mesma forma que 40197.
40197 Failover do SQL do Azure The service has encountered an error processing your request. Please try again. Error code %d. Uma atualização de software, uma falha de hardware ou outro evento de failover no SQL do Azure. Reconectar redireciona você para uma réplica íntegra. O código de erro inserido identifica o tipo de failover. Se o erro persistir, capture a ID de rastreamento da sessão e contate o suporte.
40501 Limitação de taxa do SQL do Azure The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. Limitação do mecanismo do SQL do Azure. O mínimo recomendado é um intervalo de espera de 10 segundos. A limitação sustentada indica que a carga de trabalho excedeu a alocação de recursos do banco de dados; aumente a escala da camada de serviço ou reduza a concorrência.
40613 Banco de dados indisponível Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'. O banco de dados não está disponível, geralmente durante um failover ou por um breve período durante uma operação de escala. Tente novamente após um intervalo de espera; se o problema persistir por alguns minutos, capture a ID de rastreamento da sessão e abra um chamado de suporte.
42108 Pool SQL pausado Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. O pool de SQL dedicado (Synapse) está em pausa. A nova tentativa só é bem-sucedida depois que o pool é retomado. Retome o pool explicitamente ou agende a carga de trabalho a ser executada após a retomada do pool.
42109 Retomada do pool de SQL The SQL pool is warming up. Please try again. O pool de SQL dedicado está sendo reiniciado. Tente novamente uma retirada até que o pool fique online; a inicialização normalmente leva alguns minutos.
49918 Escassez de recursos de serviços Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. No momento, o servidor não pode alocar recursos suficientes para atender à solicitação. Tente novamente em uma retirada. Se o erro persistir, aumente a capacidade do banco de dados ou do pool elástico.
49919 Limitação de taxa de operações de gerenciamento Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". Limite de concorrência no nível da assinatura para operações de gerenciamento. Reduza chamadas paralelas de criação/atualização ou escalone-as.
49920 Limitação de taxa de operações de assinatura Cannot process request. Too many operations in progress for subscription "%ld". Limite de concorrência no nível de assinatura em operações em pré-lançamento. Reduza o paralelismo ou aguarde até que as operações de pré-lançamento sejam concluídas.

Os erros no nível da instrução não estão nessa lista porque são disparados depois que a conexão é estabelecida e a falha deixa a sessão utilizável. Os erros de instrução passíveis de repetição mais comuns são 1205 (vítima de deadlock) e 1222 (tempo limite da solicitação de bloqueio). Repita a transação inteira em vez da única instrução com falha.

O texto da mensagem de erro vem de erros transitórios de conexão do SQL do Azure. Esses erros podem ser repetidos no SQL Server, no Banco de Dados SQL do Azure, no Instância Gerenciada de SQL do Azure, no Banco de Dados SQL no Microsoft Fabric e em pools SQL dedicados no Azure Synapse Analytics.

Erros durante a execução de comandos

Os seguintes erros ocorrem após a conexão ser estabelecida, enquanto um comando está sendo executado. Repita a transação inteira, não a instrução individual. Tentar novamente uma instrução dentro de uma transação pode duplicar o trabalho realizado anteriormente ou violar as garantias de ordenação da transação.

Erro Tipo de falha Message Troubleshooting
1204 Recursos do bloqueio esgotados The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions. O gerenciador de bloqueios não pode alocar mais recursos de bloqueio no servidor. Reverta a transação e tente novamente após um breve intervalo de espera. Ocorrências persistentes indicam contenção ou pressão de memória que devem ser solucionadas por meio de escalonamento ou otimização de consultas.
1205 Vítima de deadlock Transaction (Process ID %d) was deadlocked on %.*ls resources with another process and has been chosen as the deadlock victim. Rerun the transaction. O mecanismo selecionou esta sessão para resolver um interbloqueio e reverteu a transação. Reverta no lado do cliente para liberar qualquer estado restante e tente novamente toda a transação.
1222 Tempo limite da solicitação de bloqueio Lock request time out period exceeded. O motor desistiu de aguardar um bloqueio. Tente a transação novamente após um breve intervalo. Ocorrências recorrentes indicam problemas de bloqueio que a indexação, a otimização de consultas ou a revisão SET LOCK_TIMEOUT devem resolver.
3960 Conflito de atualização em isolamento de snapshot Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table '%.*ls' directly or indirectly in database '%.*ls' to update, delete, or insert the row that has been modified or deleted by another transaction. Retry the transaction or change the isolation level for the update/delete statement. Duas transações em execução sob isolamento de snapshot tentaram atualizar a mesma linha. O motor abortou essa transação. Tente novamente a transação inteira ou altere o nível de isolamento para a operação de gravação em conflito. Adicione a uma lista personalizada de erros transitórios se a sua aplicação utilizar isolamento de snapshot.

Erros em nível de instrução que refletem um problema em lote ou esquema (por exemplo, 102 erros de sintaxe, 207 coluna inválida, 2812 procedimento armazenado ausente) não são transitórios. Corrija o texto da consulta ou a vinculação ao esquema; tentar novamente não ajuda.

O texto da mensagem de erro é proveniente da exibição de catálogo sys.messages. Esses erros são gerados pelo mecanismo do SQL Server, portanto seus números de erro são os mesmos no SQL Server, no Banco de Dados SQL do Azure, no Instância Gerenciada de SQL do Azure, no banco de dados SQL do Microsoft Fabric e nos pools de SQL dedicados do Azure Synapse Analytics, independentemente do driver.

É o driver, e não o mecanismo, que expõe representações no lado do cliente de erros de tempo limite (timeout) e cancelamento de instruções (por exemplo, o tempo limite do Microsoft.Data.SqlClient -2); portanto, esses erros não constam na lista integrada. Se sua aplicação detectar esses erros separadamente, trate-os na mesma fronteira de transação dos erros do motor descritos anteriormente.

Comportamento de comandos e transações

Os provedores integrados ignoram a nova tentativa quando um comando é executado dentro de um ambiente TransactionScope ou tem um SqlTransaction anexado. O comando é executado uma vez, sem lógica de nova tentativa. Tentar novamente uma única instrução dentro de uma transação pode duplicar o trabalho realizado anteriormente ou violar a ordem pretendida da transação.

Caution

Para deadlocks e outras falhas passíveis de nova tentativa dentro de uma transação, reverta e tente novamente a transação inteira como uma única unidade. Não tente novamente apenas o comando que falhou.

Use SqlRetryLogicOption.AuthorizedSqlCondition para limitar as tentativas de comando a operações que sua aplicação pode repetir com segurança. O predicado recebe o texto do comando. Se o predicado retornar false, o comando é executado uma vez, sem lógica de repetição.

Exemplo

Para exemplos completos de conexão e comando, veja: