|
|
@ -3,6 +3,7 @@ using Volo.Abp.Caching; |
|
|
using Volo.Abp.Domain.Entities.Events; |
|
|
using Volo.Abp.Domain.Entities.Events; |
|
|
using Volo.Abp.Domain.Repositories; |
|
|
using Volo.Abp.Domain.Repositories; |
|
|
using Volo.Abp.EventBus; |
|
|
using Volo.Abp.EventBus; |
|
|
|
|
|
using Volo.Abp.Uow; |
|
|
|
|
|
|
|
|
namespace Volo.Abp.Domain.Entities.Caching; |
|
|
namespace Volo.Abp.Domain.Entities.Caching; |
|
|
|
|
|
|
|
|
@ -14,13 +15,16 @@ public abstract class EntityCacheBase<TEntity, TEntityCacheItem, TKey> : |
|
|
{ |
|
|
{ |
|
|
protected IReadOnlyRepository<TEntity, TKey> Repository { get; } |
|
|
protected IReadOnlyRepository<TEntity, TKey> Repository { get; } |
|
|
protected IDistributedCache<TEntityCacheItem, TKey> Cache { get; } |
|
|
protected IDistributedCache<TEntityCacheItem, TKey> Cache { get; } |
|
|
|
|
|
protected IUnitOfWorkManager UnitOfWorkManager { get; } |
|
|
|
|
|
|
|
|
protected EntityCacheBase( |
|
|
protected EntityCacheBase( |
|
|
IReadOnlyRepository<TEntity, TKey> repository, |
|
|
IReadOnlyRepository<TEntity, TKey> repository, |
|
|
IDistributedCache<TEntityCacheItem, TKey> cache) |
|
|
IDistributedCache<TEntityCacheItem, TKey> cache, |
|
|
|
|
|
IUnitOfWorkManager unitOfWorkManager) |
|
|
{ |
|
|
{ |
|
|
Repository = repository; |
|
|
Repository = repository; |
|
|
Cache = cache; |
|
|
Cache = cache; |
|
|
|
|
|
UnitOfWorkManager = unitOfWorkManager; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public virtual async Task<TEntityCacheItem> FindAsync(TKey id) |
|
|
public virtual async Task<TEntityCacheItem> FindAsync(TKey id) |
|
|
@ -48,6 +52,19 @@ public abstract class EntityCacheBase<TEntity, TEntityCacheItem, TKey> : |
|
|
return; |
|
|
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); |
|
|
await Cache.RemoveAsync(eventData.Entity.Id); |
|
|
|
|
|
|
|
|
|
|
|
if(UnitOfWorkManager.Current != null) |
|
|
|
|
|
{ |
|
|
|
|
|
await Cache.RemoveAsync(eventData.Entity.Id, considerUow: true); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |