我决定在我的域服务层上添加一个缓存层,以提高我正在处理的系统的性能。
我之前并没有真正使用过缓存,而且我见过的大多数示例都非常琐碎。我确信我正在处理的问题是一个熟悉的问题,但我还没有找到任何对我有帮助的东西。
简而言之,问题如下:如果我缓存了一个与其他缓存实体有关系的实体,当其中任何一个发生更改时,确保缓存始终保持最新的最佳方法是什么? 请注意,从存储库中提取实体时,实体会与其数据上下文分离。
这是一个简单的例子:
域对象:
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public int SpecID { get; set; }
public ProductSpec Spec { get; set; }
}
public class ProductSpec
{
public int ID { get; set; }
public string Name { get; set; }
public IList<Product> Products { get; set; }
public IList<ProductSpecDrawing> Drawings { get; set; }
}
public class ProductSpecDrawing
{
public int ID { get; set; }
public int ProductSpecID { get; set; }
public string Name { get; set; }
public string FileName { get; set; }
public ProductSpec Spec { get; set; }
public IList<ProductSpecDrawingRevision> Revisions { get; set; }
}
我的缓存服务的getter方法:
public override ProductSpec GetProductSpec(int productSpecID)
{
ProductSpec cachedSpec = cacheStorage.Retrieve("productSpec" + productSpecID);
if(cachedSpec == null)
{
cachedSpec = base.GetProductSpec(productSpecID); //repository lookup
cacheStorage.Store("productSpec" + productSpecID, cachedSpec);
}
return cachedSpec;
}
类似的方法缓存/检索 Product、ProductSpecDrawing 等。
现在,问题来了:例如,如果对 ProductSpecDrawing 对象进行了更新,我需要查找并更新缓存中可能引用该对象的任何其他对象,否则我可能会查看过时的数据。看起来像这样:
public override void RemoveProductSpecDrawing(int specDrawingID)
{
ProductSpecDrawing drawingToRemove = cacheStorage.Retrieve<ProductSpecDrawing>("specDrawing" + specDrawingID);
base.RemoveProductSpecDrawing(specDrawingID);
cacheStorage.Remove(drawingToRemove);
//have to update productSpec collection because we removed a drawing
cacheStorage.Store("spec" + drawingToRemove.ProductSpec.ID, base.GetProductSpec(drawingToRemove.ProductSpec.ID);
}
我认为我缓存每个实体的方式存在问题,原因有两个:数据有很多机会变得陈旧(尤其是当域变大时),并且需要在单个之后刷新潜在的许多缓存对象更新似乎会抵消任何性能提升(除非用户只是查看内容而不是编辑它们)。