diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs index 3f3b5fa42d..7e5b17b687 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs @@ -3,6 +3,7 @@ using Volo.Abp.Caching; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus; +using Volo.Abp.Uow; namespace Volo.Abp.Domain.Entities.Caching; @@ -14,13 +15,16 @@ public abstract class EntityCacheBase : { protected IReadOnlyRepository Repository { get; } protected IDistributedCache Cache { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } protected EntityCacheBase( IReadOnlyRepository repository, - IDistributedCache cache) + IDistributedCache cache, + IUnitOfWorkManager unitOfWorkManager) { Repository = repository; Cache = cache; + UnitOfWorkManager = unitOfWorkManager; } public virtual async Task FindAsync(TKey id) @@ -48,6 +52,19 @@ public abstract class EntityCacheBase : return; } + /* Why we are using double remove: + * First Cache.RemoveAsync drops the cache item in a unit of work. + * Some other application / thread may read the value from database and put it to the cache again + * before the UOW completes. + * The second Cache.RemoveAsync drops the cache item after the database transaction is complete. + * Only the second Cache.RemoveAsync may not be enough if the application crashes just after the UOW completes. + */ + await Cache.RemoveAsync(eventData.Entity.Id); + + if(UnitOfWorkManager.Current != null) + { + await Cache.RemoveAsync(eventData.Entity.Id, considerUow: true); + } } } \ No newline at end of file