From 427cf99620849b1d27d6f995cb8f76186e3ae301 Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Thu, 4 Apr 2024 16:08:28 +0300 Subject: [PATCH] EfCoreDatabaseMigrationEventHandlerBase multiple instance bug fixed --- ...EfCoreDatabaseMigrationEventHandlerBase.cs | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs index a5dcbd65cc..95b18d8221 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus.Distributed; using Volo.Abp.MultiTenancy; @@ -37,10 +38,16 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase : /// protected int MaxValueToWaitOnFailure { get; set; } = 15000; + /// + /// As minutes. + /// + protected TimeSpan DistributedLockAcquireTimeout { get; set; } = TimeSpan.FromMinutes(15); + protected ICurrentTenant CurrentTenant { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; } protected ITenantStore TenantStore { get; } protected IDistributedEventBus DistributedEventBus { get; } + protected IAbpDistributedLock DistributedLock { get; } protected ILogger> Logger { get; } protected EfCoreDatabaseMigrationEventHandlerBase( @@ -48,6 +55,7 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase : ICurrentTenant currentTenant, IUnitOfWorkManager unitOfWorkManager, ITenantStore tenantStore, + IAbpDistributedLock abpDistributedLock, IDistributedEventBus distributedEventBus, ILoggerFactory loggerFactory) { @@ -55,6 +63,7 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase : UnitOfWorkManager = unitOfWorkManager; TenantStore = tenantStore; DatabaseName = databaseName; + DistributedLock = abpDistributedLock; DistributedEventBus = distributedEventBus; Logger = loggerFactory.CreateLogger>(); @@ -186,16 +195,35 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase : { using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false)) { + async Task WaitForDistributedLockAsync(TDbContext dbContext) + { + var distributedLockHandle = await DistributedLock.TryAcquireAsync( + "DatabaseMigrationEventHandler_" + + dbContext.Database.GetConnectionString()!.ToUpperInvariant().ToMd5(), + DistributedLockAcquireTimeout + ); + + if(distributedLockHandle == null) + { + throw new AbpException($"Distributed lock could not be acquired for database migration event handler: {DatabaseName}."); + } + + return distributedLockHandle; + } + async Task MigrateDatabaseSchemaWithDbContextAsync() { var dbContext = await uow.ServiceProvider .GetRequiredService>() .GetDbContextAsync(); - if ((await dbContext.Database.GetPendingMigrationsAsync()).Any()) + await using (await WaitForDistributedLockAsync(dbContext)) { - await dbContext.Database.MigrateAsync(); - return true; + if ((await dbContext.Database.GetPendingMigrationsAsync()).Any()) + { + await dbContext.Database.MigrateAsync(); + return true; + } } return false;