Browse Source

Merge pull request #19506 from abpframework/bug/multiple-instance-migration

Database migration event handler multiple instance bug fixed
pull/19511/head
Halil İbrahim Kalkan 2 years ago
committed by GitHub
parent
commit
f85b3dd5d6
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 34
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Migrations/EfCoreDatabaseMigrationEventHandlerBase.cs

34
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<TDbContext> :
/// </summary>
protected int MaxValueToWaitOnFailure { get; set; } = 15000;
/// <summary>
/// As minutes.
/// </summary>
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<EfCoreDatabaseMigrationEventHandlerBase<TDbContext>> Logger { get; }
protected EfCoreDatabaseMigrationEventHandlerBase(
@ -48,6 +55,7 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase<TDbContext> :
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
ITenantStore tenantStore,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory)
{
@ -55,6 +63,7 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase<TDbContext> :
UnitOfWorkManager = unitOfWorkManager;
TenantStore = tenantStore;
DatabaseName = databaseName;
DistributedLock = abpDistributedLock;
DistributedEventBus = distributedEventBus;
Logger = loggerFactory.CreateLogger<EfCoreDatabaseMigrationEventHandlerBase<TDbContext>>();
@ -186,16 +195,35 @@ public abstract class EfCoreDatabaseMigrationEventHandlerBase<TDbContext> :
{
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
async Task<IAsyncDisposable> 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<bool> MigrateDatabaseSchemaWithDbContextAsync()
{
var dbContext = await uow.ServiceProvider
.GetRequiredService<IDbContextProvider<TDbContext>>()
.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;

Loading…
Cancel
Save