Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
İpucu
Bu içerik, .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan Kapsayıcılı .NET Uygulamaları için .NET Mikro Hizmet Mimarisi e-Kitabı'ndan bir alıntıdır.
Azure SQL DB için Entity Framework (EF) Core zaten iç veritabanı bağlantısı dayanıklılığı ve yeniden deneme mantığı sağlar. Ancak dayanıklı EF Core bağlantılarınaDbContextolmak istiyorsanız her bağlantı için Entity Framework yürütme stratejisini etkinleştirmeniz gerekir.
Örneğin, EF Core bağlantı düzeyinde aşağıdaki kod, bağlantı başarısız olursa yeniden denenen dayanıklı SQL bağlantılarını etkinleştirir.
// Program.cs from any ASP.NET Core Web API
// Other code ...
builder.Services.AddDbContext<CatalogContext>(options =>
{
options.UseSqlServer(
builder.Configuration["ConnectionString"],
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 10,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
});
});
Önemli
Microsoft, kullanılabilir en güvenli kimlik doğrulama akışını kullanmanızı önerir. Azure SQL'e bağlanıyorsanız önerilen kimlik doğrulama yöntemi Azure kaynakları için Yönetilen Kimlikler'dir.
BeginTransaction ve birden çok DbContext kullanarak yürütme stratejileri ve açık işlemler
EF Core bağlantılarında yeniden denemeler etkinleştirildiğinde, EF Core kullanarak gerçekleştirdiğiniz her işlem kendi yeniden denenebilir işlemi olur. Her sorgu ve her çağrısı SaveChanges , geçici bir hata oluşursa birim olarak yeniden denenir.
Ancak kodunuz kullanarak BeginTransactionbir işlem başlatırsa, birim olarak ele alınması gereken kendi işlem grubunuzu tanımlarsınız. Bir hata oluşursa işlem içindeki her şeyin geri alınması gerekir.
EF yürütme stratejisini (yeniden deneme ilkesi) kullanırken bu işlemi yürütmeye çalışırsanız ve birden çok DbContexts'ten çağırırsanız SaveChanges aşağıdakine benzer bir özel durumla karşı karşıyasınız:
System.InvalidOperationException: Yapılandırılan yürütme stratejisi 'SqlServerRetryingExecutionStrategy' kullanıcı tarafından başlatılan işlemleri desteklemiyor. İşlemdeki tüm işlemleri yeniden denenebilir bir birim olarak yürütmek için 'DbContext.Database.CreateExecutionStrategy()' tarafından döndürülen yürütme stratejisini kullanın.
Çözüm, EF yürütme stratejisini, yürütülmesi gereken her şeyi temsil eden bir temsilciyle el ile çağırmaktır. Geçici bir hata oluşursa yürütme stratejisi temsilciyi yeniden çağırır. Örneğin aşağıdaki kod, bir ürünü güncelleştirirken ve sonra farklı bir DbContext kullanması gereken ProductPriceChangedIntegrationEvent nesnesini kaydederken iki birden çok DbContext (_catalogContext ve IntegrationEventLogContext) içeren eShopOnContainers'da nasıl uygulandığını gösterir.
public async Task<IActionResult> UpdateProduct(
[FromBody]CatalogItem productToUpdate)
{
// Other code ...
var oldPrice = catalogItem.Price;
var raiseProductPriceChangedEvent = oldPrice != productToUpdate.Price;
// Update current product
catalogItem = productToUpdate;
// Save product's data and publish integration event through the Event Bus
// if price has changed
if (raiseProductPriceChangedEvent)
{
//Create Integration Event to be published through the Event Bus
var priceChangedEvent = new ProductPriceChangedIntegrationEvent(
catalogItem.Id, productToUpdate.Price, oldPrice);
// Achieving atomicity between original Catalog database operation and the
// IntegrationEventLog thanks to a local transaction
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(
priceChangedEvent);
// Publish through the Event Bus and mark the saved event as published
await _catalogIntegrationEventService.PublishThroughEventBusAsync(
priceChangedEvent);
}
// Just save the updated product because the Product's Price hasn't changed.
else
{
await _catalogContext.SaveChangesAsync();
}
}
Birincisi DbContext , _catalogContext ikincisi DbContext nesnenin _catalogIntegrationEventService içindedir. İşleme eylemi, EF yürütme stratejisi kullanılarak tüm DbContext nesneler arasında gerçekleştirilir.
Bu birden çok DbContext işlemeyi SaveEventAndCatalogContextChangesAsync başarmak için aşağıdaki kodda gösterildiği gibi bir ResilientTransaction sınıf kullanır:
public class CatalogIntegrationEventService : ICatalogIntegrationEventService
{
//…
public async Task SaveEventAndCatalogContextChangesAsync(
IntegrationEvent evt)
{
// Use of an EF Core resiliency strategy when using multiple DbContexts
// within an explicit BeginTransaction():
// https://learn.microsoft.com/ef/core/miscellaneous/connection-resiliency
await ResilientTransaction.New(_catalogContext).ExecuteAsync(async () =>
{
// Achieving atomicity between original catalog database
// operation and the IntegrationEventLog thanks to a local transaction
await _catalogContext.SaveChangesAsync();
await _eventLogService.SaveEventAsync(evt,
_catalogContext.Database.CurrentTransaction.GetDbTransaction());
});
}
}
ResilientTransaction.ExecuteAsync yöntemi temel olarak geçirilen DbContext (_catalogContext) işleminden bir işlem başlatır ve ardından dosyasındaki EventLogService değişiklikleri IntegrationEventLogContext kaydetmek için bu işlemi kullanır ve ardından işlemin tamamını işler.
public class ResilientTransaction
{
private DbContext _context;
private ResilientTransaction(DbContext context) =>
_context = context ?? throw new ArgumentNullException(nameof(context));
public static ResilientTransaction New (DbContext context) =>
new ResilientTransaction(context);
public async Task ExecuteAsync(Func<Task> action)
{
// Use of an EF Core resiliency strategy when using multiple DbContexts
// within an explicit BeginTransaction():
// https://learn.microsoft.com/ef/core/miscellaneous/connection-resiliency
var strategy = _context.Database.CreateExecutionStrategy();
await strategy.ExecuteAsync(async () =>
{
await using var transaction = await _context.Database.BeginTransactionAsync();
await action();
await transaction.CommitAsync();
});
}
}
Ek kaynaklar
ASP.NET MVC Uygulamasında EF ile Bağlantı Dayanıklılığı ve Komut Kesme
https://learn.microsoft.com/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-applicationCesar de la Torre. Dayanıklı Entity Framework Core SQL Bağlantılarını ve İşlemlerini Kullanma
https://devblogs.microsoft.com/cesardelatorre/using-resilient-entity-framework-core-sql-connections-and-transactions-retries-with-exponential-backoff/