1

作業中のシステムのパフォーマンスを向上させるために、ドメインサービスレイヤーの上にキャッシュレイヤーを追加することにしました。

私はこれまでキャッシュを実際に使用したことがなく、私が見た例のほとんどは本当に些細なものです。私が取り組んでいる問題はおなじみの問題だと確信していますが、私はまだ私を助けてくれたものを突き止めることができませんでした。

問題は、簡単に言うと、次のとおりです。他のキャッシュされたエンティティと関係のあるエンティティをキャッシュした場合、それらのいずれかに変更があったときにキャッシュが常に最新であることを確認するための最良の方法は何ですか。 ?リポジトリからプルされると、エンティティはデータコンテキストから切り離されることに注意してください。

簡単な例を次に示します。

ドメインオブジェクト:

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; }
}

私のキャッシュサービスのゲッターメソッド:

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);
}

各エンティティをキャッシュする方法には、いくつかの理由で問題があると思います。データが古くなる可能性が多く(特にドメインが大きくなると)、1回の実行後にキャッシュされたオブジェクトを更新する必要がある可能性があります。更新すると、パフォーマンスの向上が無効になるようです(ユーザーが表示しているだけで編集していない場合を除く)。

4

0 に答える 0