Treinamento
Módulo
Implementar resiliência em um microsserviço nativo de nuvem - Training
Este módulo orienta você pela implementação da resiliência em um aplicativo de microsserviços do .NET em um Serviço de Kubernetes.
Não há mais suporte para esse navegador.
Atualize o Microsoft Edge para aproveitar os recursos, o suporte técnico e as atualizações de segurança mais recentes.
Observação
EF6 em diante apenas: os recursos, as APIs etc. discutidos nessa página foram introduzidos no Entity Framework 6. Se você estiver usando uma versão anterior, algumas ou todas as informações não se aplicarão.
Os aplicativos que se conectam a um servidor de banco de dados sempre foram vulneráveis a quebras de conexão devido a falhas de back-end e instabilidade de rede. No entanto, em um ambiente baseado em LAN que trabalha com servidores de banco de dados dedicados, esses erros são raros e a lógica extra para lidar com essas falhas não são frequentemente necessárias. Com o aumento de servidores de banco de dados baseados em nuvem, como o Banco de Dados SQL do Windows Azure e conexões em redes menos confiáveis, agora é mais comum que ocorram quebras de conexão. Isso pode ser devido a técnicas defensivas que os bancos de dados de nuvem usam para garantir a imparcialidade do serviço, como limitação de conexão ou instabilidade na rede, causando tempos limite intermitentes e outros erros transitórios.
Resiliência de conexão refere-se à capacidade do EF de repetir automaticamente todos os comandos que falham devido a essas quebras de conexão.
A repetição de conexão é cuidada por uma implementação da interface IDbExecutionStrategy. As implementações do IDbExecutionStrategy serão responsáveis por aceitar uma operação e, se ocorrer uma exceção, determinar se uma repetição é apropriada e repetir a tentativa se ela for. Há quatro estratégias de execução que são enviadas com EF:
Observação
As estratégias de execução 2 e 4 são incluídas no provedor do SQL Server que é fornecido com o EF, que está no assembly EntityFramework.SqlServer e foi projetado para funcionar com o SQL Server.
A maneira mais fácil de informar o EF para usar uma estratégia de execução é com o método SetExecutionStrategy da classe DbConfiguration :
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
}
}
Esse código informa ao EF para usar o SqlAzureExecutionStrategy ao se conectar ao SQL Server.
O construtor de SqlAzureExecutionStrategy pode aceitar dois parâmetros, MaxRetryCount e MaxDelay. A contagem do MaxRetry é o número máximo de vezes que a estratégia repetirá a tentativa. O MaxDelay é um TimeSpan que representa o atraso máximo entre as tentativas que a estratégia de execução usará.
Para definir o número máximo de repetições como 1 e o atraso máximo para 30 segundos, você executaria o seguinte:
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetExecutionStrategy(
"System.Data.SqlClient",
() => new SqlAzureExecutionStrategy(1, TimeSpan.FromSeconds(30)));
}
}
O SqlAzureExecutionStrategy repetirá a tentativa na primeira vez que ocorrer uma falha transitória, mas atrasará mais tempo entre cada repetição até que o limite máximo de repetição seja excedido ou o tempo total atinja o atraso máximo.
As estratégias de execução tentarão apenas um número limitado de exceções que geralmente são transitórias. Você ainda precisará lidar com outros erros, bem como capturar a exceção RetryLimitExceededed para o caso em que um erro não é transitório ou leva muito tempo para se resolver.
Há algumas limitações conhecidas ao usar uma estratégia de execução de repetição:
Por padrão, o EF6 e a versão posterior armazenarão em buffer os resultados da consulta em vez de transmiti-los. Se você quiser que os resultados sejam transmitidos, poderá usar o método AsStreaming para alterar uma consulta LINQ to Entities para streaming.
using (var db = new BloggingContext())
{
var query = (from b in db.Blogs
orderby b.Url
select b).AsStreaming();
}
}
Não há suporte para streaming quando uma estratégia de execução de repetição é registrada. Essa limitação existe porque a conexão pode remover parte dos resultados que estão sendo retornados. Quando isso ocorre, o EF precisa executar novamente toda a consulta, mas não tem uma maneira confiável de saber quais resultados já foram retornados (os dados podem ter sido alterados desde que a consulta inicial foi enviada, os resultados podem voltar em uma ordem diferente, os resultados podem não ter um identificador exclusivo, etc.).
Quando você configura uma estratégia de execução que resulta em novas tentativas, há algumas limitações em relação ao uso de transações.
Por padrão, o EF executará todas as atualizações de banco de dados em uma transação. Você não precisa fazer nada para habilitar isso, o EF sempre faz isso automaticamente.
Por exemplo, no código a seguir, SaveChanges é executado automaticamente em uma transação. Se SaveChanges falhasse depois de inserir um dos novos Sites, a transação seria revertida e nenhuma alteração aplicada ao banco de dados. O contexto também é deixado em um estado que permite que SaveChanges seja chamado para repetir a tentativa aplicar as alterações.
using (var db = new BloggingContext())
{
db.Blogs.Add(new Site { Url = "http://msdn.com/data/ef" });
db.Blogs.Add(new Site { Url = "http://blogs.msdn.com/adonet" });
db.SaveChanges();
}
Ao não usar uma estratégia de execução de repetição, você pode encapsular várias operações em uma única transação. Por exemplo, o código a seguir encapsula duas chamadas SaveChanges em uma única transação. Se qualquer parte de uma das operações falhar, nenhuma das alterações será aplicada.
using (var db = new BloggingContext())
{
using (var trn = db.Database.BeginTransaction())
{
db.Blogs.Add(new Site { Url = "http://msdn.com/data/ef" });
db.Blogs.Add(new Site { Url = "http://blogs.msdn.com/adonet" });
db.SaveChanges();
db.Blogs.Add(new Site { Url = "http://twitter.com/efmagicunicorns" });
db.SaveChanges();
trn.Commit();
}
}
Não há suporte para isso ao usar uma estratégia de execução de repetição porque o EF não está ciente de nenhuma operação anterior e de como repeti-las. Por exemplo, se o segundo SaveChanges falhou, o EF não tem mais as informações necessárias para repetir a tentativa da primeira chamada SaveChanges.
A solução é usar manualmente a estratégia de execução e dar a ela todo o conjunto de lógica a ser executado, para que ela possa repetir tudo se uma das operações falhar. Quando uma estratégia de execução derivada de DbExecutionStrategy estiver em execução, ela suspenderá a estratégia de execução implícita usada em SaveChanges.
Observe que todos os contextos devem ser construídos dentro do bloco de código a ser repetido. Isso garante que estamos começando com um estado limpo para cada repetição.
var executionStrategy = new SqlAzureExecutionStrategy();
executionStrategy.Execute(
() =>
{
using (var db = new BloggingContext())
{
using (var trn = db.Database.BeginTransaction())
{
db.Blogs.Add(new Blog { Url = "http://msdn.com/data/ef" });
db.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
db.SaveChanges();
db.Blogs.Add(new Blog { Url = "http://twitter.com/efmagicunicorns" });
db.SaveChanges();
trn.Commit();
}
}
});
Comentários do .NET
O .NET é um projeto código aberto. Selecione um link para fornecer comentários:
Treinamento
Módulo
Implementar resiliência em um microsserviço nativo de nuvem - Training
Este módulo orienta você pela implementação da resiliência em um aplicativo de microsserviços do .NET em um Serviço de Kubernetes.
Documentação
Resiliência de conexão – EF Core
Usando a resiliência de conexão para repetir comandos com falha automaticamente com o Entity Framework Core
Implementar conexões SQL resilientes com o Entity Framework Core - .NET
Saiba como implementar conexões SQL resilientes com o Entity Framework Core. Essa técnica é importante principalmente ao usar o Banco de Dados SQL do Azure na nuvem.
Trabalhando com Transações – EF6
Trabalhando com Transações no Entity Framework 6
Gerenciamento de transações para atomicidade ao salvar dados com o Entity Framework Core