Fornecedores de lógica de retentativa incorporados no SqlClient

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

Baixar ADO.NET

Microsoft.Data.SqlClient.SqlConfigurableRetryFactory cria provedores para agendamentos comuns de novas tentativas. A lógica de repetição configurável está desativada por defeito. Atribua um provedor a SqlConnection.RetryLogicProvider ou SqlCommand.RetryLogicProvider para ativá-lo nesse objeto.

Escolha um mecanismo de repetição

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 nova tentativa.
SqlConfigurableRetryFactory.CreateNoneRetryProvider Não tenta novamente. Este fornecedor é o padrão.

Os mecanismos fixos, incrementais e exponenciais adicionam uma variação aleatória a cada um dos intervalos. O jitter reduz as rajadas sincronizadas de retentativas quando muitos clientes enfrentam a mesma falha.

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

Lista de erros transitórios incorporada

Quando SqlRetryLogicOption.TransientErrors é null, os fornecedores incorporados 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 autenticação 233, 997, 10060
Disponibilidade da base de dados durante o início de sessão 4060, 4221
Nível de instrução 1204, 1205, 1222
Limite de recursos ou estrangulamento 10928, 10929, 40501, 49918, 49919, 49920
SQL do Azure service failover 40143, 40197, 40540, 40613
Estado do pool de SQL dedicado 42108, 42109

Cada erro é descrito nas secções seguintes.

Importante

A definição TransientErrors substitui a lista incorporada. Não acrescenta à lista. Inclua todos os erros que o prestador deve tentar novamente.

No Microsoft.Data.SqlClient 7.0, SqlConfigurableRetryFactory.BaselineTransientErrors expõe a lista incorporada como uma coleção só de leitura. Use-o para estender a linha 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 do controlador, crie uma coleção pertencente à aplicação que contenha os erros de base de que precisa e os erros adicionais. Antes de copiar uma linha base, selecione a etiqueta de origem SqlClient que corresponda à versão do seu pacote instalado e inspecione SqlConfigurableRetryFactory.cs. A lista na main agência pode mudar após a libertação do seu pacote.

Erros durante o estabelecimento da ligação

Os seguintes erros permitem nova tentativa na lista integrada ou justificam ser adicionados a TransientErrors além da lista integrada.

Os seguintes erros podem ser transitórios quando ocorrem durante o estabelecimento da ligação ou ao enviar um pedido ao servidor. Tente novamente após um curto intervalo de espera limitado. Erros que persistem depois de algumas tentativas geralmente indicam um problema de configuração, como servidor errado, permissões em falta, definições de encriptação incompatíveis ou quota esgotada, que uma nova tentativa não resolve.

Erro Tipo de falha Message Troubleshooting
64 Transporte durante o início de sessão 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 ligação TCP cai a meio do handshake. Não é uma falha de credenciais. Se persistir, verifique se há instabilidade na rede do lado do cliente ou um dispositivo intermédio que interrompa ligações semiestabelecidas.
233 Transporte pré-login ou TLS The client was unable to establish a connection because of an error during connection initialization process before login. O servidor normalmente devolve este erro quando não consegue aceitar a ligação devido a esgotamento de recursos, limite de ligação ou um cliente não suportado. Não é uma falha de credenciais. Verifica o estado do servidor e depois verifica o timeout de login do cliente, as definições do TLS e a compatibilidade da versão cliente/servidor TLS.
4060 Disponibilidade ou acesso à base de dados Cannot open database "%.*ls" requested by the login. The login failed. O login autentica, mas não consegue abrir a base de dados solicitada. Causas transitórias incluem a base de dados estar em transição (failover, restauração, escalabilidade) ou em pausa automática. Causas persistentes (a base de dados não existe, o login não tem acesso) não serão corrigidas por uma nova tentativa; Verifique o nome da base de dados, o mapeamento de login e o estado da base 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 início de sessão porque as versões de linha estão em falta para transações que estavam em curso quando a réplica foi reciclada. Reverta ou compromete as transações ativas no principal para resolver o problema. Atenue evitando transações de escrita longas no 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 interrompe a ligação. Verifique a saúde da rede do lado do cliente e qualquer firewall local ou cliente VPN.
10054 Reinício do transporte remoto 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 um reset TCP. Causas comuns: o processo peer crashava, um firewall injetava um reset, ou o gateway SQL do Azure fechava uma ligação inativa. Para casos de reposição da ligação por inatividade, ative o keepalive de TCP no cliente ou reduza o tempo limite de inatividade do conjunto de ligações.
10060 Tempo limite de ligação A connection attempt failed because the connected party did not properly respond after a period of time. O servidor ou um dispositivo de rede intermédio não respondia antes do tempo limite da ligação TCP. Verifique a saúde do servidor, o encaminhamento, as regras do firewall e se o host e a porta configurados são acessíveis.
10928 Limite de recursos da base de dados Resource ID: %d. The %s limit for the database is %d and has been reached. A base de dados ultrapassa um limite de governação de recursos do SQL do Azure. O ID de Recurso 1 indica o limite de trabalhadores; O ID do Recurso 2 indica o limite de sessão. Identifique o tipo de limite a partir da mensagem, depois reduza a concorrência, escale a base de dados ou encurta as operações de longa duração que detêm o recurso.
10929 Limitação da base 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. A base de dados ultrapassa a sua garantia mínima e o servidor subjacente está a limitar. Retry normalmente tem sucesso quando a carga do vizinho diminui. Ocorrências prolongadas indicam que precisa de um nível de serviço mais elevado ou de um ambiente menos ruidoso.
40020, 40143, 40166, 40540 Subcódigo de failover do SQL do Azure Reportado na posição Error code %d do erro 40197 durante a comutação pós-falha. Subcódigos incorporados numa mensagem de failover 40197 que alguns percursos apresentam como o número de erro de nível superior. Trata-os da mesma forma que 40197.
40197 SQL do Azure failover The service has encountered an error processing your request. Please try again. Error code %d. Uma atualização de software, falha de hardware ou outro evento de failover no SQL do Azure. Ao restabelecer a ligação, será encaminhado para uma réplica em bom estado. O código de erro incorporado identifica o tipo de failover. Se o erro persistir, regista o ID de rastreamento da sessão e contacta o suporte.
40501 SQL do Azure throttling The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. Limitação do motor do SQL do Azure. O intervalo mínimo recomendado é de 10 segundos. A limitação persistente indica que a carga de trabalho excedeu a alocação de recursos da base de dados; aumente o escalão de serviço ou reduza a concorrência.
40613 Base 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'. A base de dados está indisponível, geralmente a meio do failover ou brevemente durante uma operação de escala. Tente novamente com intervalo progressivo; se o problema persistir durante mais do que alguns minutos, registe o ID de rastreio da sessão e abra um pedido 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 dedicado de SQL (Synapse) está em estado de pausa. A nova tentativa só é bem-sucedida depois de o pool ser reativado. Retome explicitamente o pool ou programe a carga de trabalho para ser executada depois de o pool ser retomado.
42109 Pool de SQL a retomar The SQL pool is warming up. Please try again. O pool dedicado de SQL está a recomeçar. Tente novamente um recuo até a piscina estar online; O aquecimento normalmente demora alguns minutos.
49918 Escassez de recursos de serviço Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. O servidor não consegue atualmente alocar recursos suficientes para satisfazer o pedido. Tente novamente após um intervalo de espera. Se o erro persistir, amplie a base de dados ou o elastic pool.
49919 Limitação das operações de gestão Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". Limite de concorrência a nível da subscrição para operações de gestão. Reduza as chamadas paralelas de criação/atualização ou escalone-as.
49920 Limitação por operação de subscrição Cannot process request. Too many operations in progress for subscription "%ld". Limite de concorrência ao nível de subscrição para operações em voo. Reduzir o paralelismo ou esperar que as operações em voo se esgotem.

Os erros ao nível da instrução não constam desta lista porque ocorrem depois de a ligação ter sido estabelecida e a falha não inutiliza a sessão. Os erros mais comuns das instruções passíveis de repetição são 1205 (vítima de impasse [deadlock]) e 1222 (tempo limite do pedido de bloqueio). Tente novamente toda a transação em vez do único extrato falhado.

O texto da mensagem de erro provém de erros de ligação transitória do SQL do Azure. Estes erros podem ser repetidos no SQL Server, no Base de Dados SQL do Azure, no Azure SQL Managed Instance, na base de dados SQL no Microsoft Fabric e nos pools SQL dedicados no Azure Synapse Analytics.

Erros durante a execução de comandos

Os seguintes erros ocorrem após o estabelecimento de uma ligação, enquanto um comando está a ser executado. Tente novamente toda a transação, não o extrato individual. Repetir uma instrução dentro de uma transação pode duplicar operações anteriores 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 gestor de bloqueios não pode alocar mais recursos de bloqueio no servidor. Reverta a transação e tente novamente após um curto intervalo de espera. Ocorrências prolongadas indicam contenção ou pressão de memória que o aumento de escala ou a otimização de consultas devem resolver.
1205 Vítima do impasse 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 bloqueio e reverteu a respetiva transação. Reverter no lado do cliente para libertar qualquer estado remanescente e, em seguida, repetir toda a transação.
1222 Tempo limite do pedido de bloqueio Lock request time out period exceeded. O motor desistiu de esperar pelo bloqueio. Tente novamente a transação após um curto intervalo. Ocorrências recorrentes indicam bloqueios que devem ser resolvidos através da indexação, da otimização de consultas ou da SET LOCK_TIMEOUT revisão.
3960 Conflito de atualização de isolamento de snapshots 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 com isolamento snapshot tentaram atualizar a mesma linha. O motor abortou esta transação. Tente novamente a transação inteira, ou altere o nível de isolamento para a operação de escrita em conflito. Adicione a uma lista personalizada de erros transitórios se a sua aplicação usar isolamento de instantâneos.

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

O texto da mensagem de erro provém da vista de catálogo sys.messages. Estes erros vêm do motor SQL Server, pelo que os seus números são os mesmos em SQL Server, Base de Dados SQL do Azure, Azure SQL Managed Instance, base de dados SQL no Microsoft Fabric e pools SQL dedicados em Azure Synapse Analytics, independentemente do driver.

O driver, e não o motor, apresenta representações no lado do cliente de erros de tempo limite e de cancelamento de instrução (por exemplo, o timeout do Microsoft.Data.SqlClient -2), pelo que estes erros não constam da lista integrada. Se a sua aplicação detetar estes erros separadamente, trate-os na mesma fronteira de transação dos erros do motor descritos anteriormente.

Comportamento de comandos e transações

Os fornecedores incorporados saltam a retentativa quando um comando é executado dentro de um ambiente TransactionScope ou tem um SqlTransaction adjunto. O comando é executado uma vez sem lógica de repetição. Tentar novamente uma instrução isolada dentro de uma transação pode duplicar operações anteriores ou violar a ordem pretendida da transação.

Caution

Para interbloqueios e outras falhas passíveis de nova tentativa dentro de uma transação, anula e repete a transação inteira como uma única unidade. Não tentes repetir só o comando que falhou.

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

Example

Para exemplos completos de ligação e comando, veja: