2009-04-07 10 views
1

次の手法を使用して、データベースへの呼び出しをキャッシュします。この関数は、自分のリポジトリに存在します。非常にシンプルなキャッシング - これはo.kです。技術?

Public Shared Function GetByStoreURL(ByVal StoreURL As String) As Model.Partner 

     Dim key As String = StoreURL 
     If Current.Cache(key) Is Nothing Then 
      Dim objPartner = Model.DB.Select().From(Tables.Partner).Where(Partner.Columns.StoreURL).IsEqualTo(StoreURL.ToString).And(Partner.Columns.IsDeleted).IsNotEqualTo(1).ExecuteSingle(Of Partner)() 
      Current.Cache.Add(key, objPartner, Nothing, Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(60), CacheItemPriority.NotRemovable, Nothing) 
     End If 

     Return DirectCast(Current.Cache(key), Model.Partner) 

    End Function 

この手法には欠陥がありますか?とてもシンプルに見え、それは素晴らしい仕事をしているようです。

答えて

3

唯一の問題は、(データの変更により)キャッシュを無効にし、ロードバランス/クラスタ環境で実行している場合です。その可能性があるならば、ファイルの依存関係を追加したり、Velocityのような分散キャッシングシステムを見ることができます。

あなたは、あなたがスケールアウトしないと、あなたが潜在的に「古い」の記録を持つ気にしない、その罰金:-)実は

+0

ええ、私がキャッシュしているものは古くなる可能性があります – Slee

1

だことを実行する必要がない場合は、スタッフ間違ったたくさんのここで最も明白なのは、Single responsibility principleです。基本的に、関数は1つの厳密に定義されたタスクのみを実行する必要があります(つまり、DBからPartnerを取得します)。

次はマルチスレッドになります。 Webサイトは本質的にマルチスレッド化されているので、これを考慮する必要があります。具体的には、If Current.Cache(key) Is NothingReturn DirectCast(Current.Cache(key), Model.Partner)の呼び出しの間にアイテムをキャッシュから削除することができます。この問題を解決するにはロックが必要ですが、これによりさらに機能が拡張されます(最初の段落を参照)。

さらに、DBコードの実行中にアイテムをキャッシュに追加することができます。 Cache.Addは値がすでに存在する同じキーで上書きされないため(マルチスレッドと考える)、エラーが発生します。

最後に、StoreURLの一意性について質問します。