Browse Source

PErmission management: complete UOW inside the common lock to prevent conflicts.

pull/16276/head
Halil İbrahim Kalkan 3 years ago
parent
commit
c61d97f09d
  1. 54
      modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/StaticFeatureSaver.cs

54
modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/StaticFeatureSaver.cs

@ -27,6 +27,8 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency
protected AbpFeatureOptions FeatureOptions { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
protected AbpDistributedCacheOptions CacheOptions { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
public StaticFeatureSaver(
IStaticFeatureDefinitionStore staticStore,
@ -38,7 +40,8 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency
IApplicationInfoAccessor applicationInfoAccessor,
IAbpDistributedLock distributedLock,
IOptions<AbpFeatureOptions> featureManagementOptions,
ICancellationTokenProvider cancellationTokenProvider)
ICancellationTokenProvider cancellationTokenProvider,
IUnitOfWorkManager unitOfWorkManager)
{
StaticStore = staticStore;
FeatureGroupRepository = featureGroupRepository;
@ -48,12 +51,12 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency
ApplicationInfoAccessor = applicationInfoAccessor;
DistributedLock = distributedLock;
CancellationTokenProvider = cancellationTokenProvider;
UnitOfWorkManager = unitOfWorkManager;
FeatureOptions = featureManagementOptions.Value;
CacheOptions = cacheOptions.Value;
}
[UnitOfWork]
public virtual async Task SaveAsync()
public async Task SaveAsync()
{
await using var applicationLockHandle = await DistributedLock.TryAcquireAsync(
GetApplicationDistributedLockKey()
@ -99,19 +102,40 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency
throw new AbpException("Could not acquire distributed lock for saving static features!");
}
var hasChangesInGroups = await UpdateChangedFeatureGroupsAsync(featureGroupRecords);
var hasChangesInFeatures = await UpdateChangedFeaturesAsync(featureRecords);
if (hasChangesInGroups ||hasChangesInFeatures)
using (var unitOfWork = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
{
await Cache.SetStringAsync(
GetCommonStampCacheKey(),
Guid.NewGuid().ToString(),
new DistributedCacheEntryOptions {
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
},
CancellationTokenProvider.Token
);
try
{
var hasChangesInGroups = await UpdateChangedFeatureGroupsAsync(featureGroupRecords);
var hasChangesInFeatures = await UpdateChangedFeaturesAsync(featureRecords);
if (hasChangesInGroups ||hasChangesInFeatures)
{
await Cache.SetStringAsync(
GetCommonStampCacheKey(),
Guid.NewGuid().ToString(),
new DistributedCacheEntryOptions {
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
},
CancellationTokenProvider.Token
);
}
}
catch
{
try
{
await unitOfWork.RollbackAsync();
}
catch
{
/* ignored */
}
throw;
}
await unitOfWork.CompleteAsync();
}
}

Loading…
Cancel
Save