2010-11-11 53 views
5

問題

我們有一個複雜的域模型。爲了避免性能問題,大多數列表(由域對象生成)被緩存。一切正常,直到第一個域對象改變。必須刷新緩存中的所有依賴列表 - 問題是:如何?域對象更改 - 需要緩存列表刷新

  • Domain對象:房子
  • 行動:房子的名稱已更改
  • 影響:所有的列表(containts房子的名字)是失日期,需要更新

解決方案

毫無疑問,有一個非常簡單的方法:在保存一個域對象後,我們手動刷新代碼中的所有列表。

僞代碼

repository.Save(save); 

cacheManager.Invalidate("HouseList"); 
cacheManager.Invalidate("OrderedHouseList"); 
cacheManager.Invalidate("HousecombinedWithResidentsList"); 
... 

所以問題是:我們要刷新一切手動。我在尋找更好的解決方案,讓我們說:

  • 面向方面的方式W/PostSharp或溫莎
  • 觀察員或基於事件的技術
  • CQRS它是關於分離查詢和命令,但這種觀念也許是太許多。

任何想法或經驗?

回答

1

此問題的答案很複雜,因爲您的要求不明確。數據可以陳舊嗎?如果是這樣,多久?

根據您發佈的信息有限,我建議「緩存」的視圖僅僅是對真實數據的查詢。查詢本身可以週期性地刷新其緩存結果。

+0

良好的後續問題。 – 2010-11-12 20:26:26

+0

「數據可能陳舊嗎?如果是這樣,多長時間?」:大概1小時,也許1年。主要問題來自不穩定的業務領域。 – boj 2010-11-12 20:28:27

0

我想說,如果您的插入/更新/刪除修改其中一個列表的內容,您應該重新查詢列表。我的應用程序中有一些緩存的數據表,我使用下面的結構集合來維護它們。這樣,很容易清除整個緩存,並且當我詢問特定的數據表時,我會檢查緩存中是否存在未過期的數據。

Protected Structure CachedDT 

    #Region "Local Variables" 

    Public TheDT As DataTable 
    Public TheExpirationTime As DateTime 
    Public TheUniqueIdentifier As String 

    #End Region 'Local Variables 

End Structure 

Protected cCachedDTs As Dictionary(Of String, CachedDT) = New Dictionary(Of String, CachedDT) 

這些生活在我的基類中查詢數據庫的對象。使用高速緩存的數據表的一個例子是:

<System.Diagnostics.DebuggerStepThrough> _ 
    Public Overrides Function GetPermissionsSystem(ByVal SystemUserName As String) As DataTable 
     Try 
      Dim oCmd As New SqlCommand 
      Dim aDpt As New SqlDataAdapter 
      Dim aDst As New DataSet 
      Dim theCached As CachedDT 
      Dim theCacheName As String = "GetPermissionsSystem|" & SystemUserName 
      If cCachedDTs.ContainsKey(theCacheName) Then 
       theCached = cCachedDTs.Item(theCacheName) 
       If theCached.TheExpirationTime < DateTime.Now Then 
        cCachedDTs.Remove(theCacheName) 
       Else 
        Return theCached.TheDT 
       End If 
      End If 
      With oCmd 
       .Connection = MyBase.Conn 
       .CommandType = CommandType.StoredProcedure 
       .CommandTimeout = MyBase.TimeoutShort 
       .CommandText = Invoicing.GetPermissionsSystem 
       .Parameters.Add(GP("@SystemUserName", SystemUserName)) 
      End With 
      aDpt.SelectCommand = oCmd 
      aDpt.Fill(aDst) 
      theCached = New CachedDT 
      With theCached 
       .TheUniqueIdentifier = theCacheName 
       .TheExpirationTime = DateTime.Now.AddSeconds(10) 
       .TheDT = aDst.Tables(0) 
      End With 
      cCachedDTs.Add(theCached.TheUniqueIdentifier, theCached) 
      Return aDst.Tables(0) 
     Catch sqlex As SqlException 
      MyBase.HandelEX(sqlex) 
     Catch ex As Exception 
      MyBase.HandleEX(ex) 
     Finally 
      MyBase.CloseConn() 
     End Try 
    End Function 

在上面的例子中,功能檢查高速緩存看到一個合適的對象是否存在。如果確實如此,則返回而不是再次訪問數據庫。最後,新的對象被添加到緩存中。

你所要做的只是提供一些從緩存中刪除特定列表的方法。然後,當你做一個插入/更新/刪除,確保你清除適當的項目。

+0

對不起,代碼在VB中,而不是C#。 http://www.developerfusion.com/tools/convert/csharp-to-vb/會爲你轉換它,如果它是一個合適的探測解決方案。 – 2010-11-12 16:12:43

+0

謝謝,但這只是關於緩存(我更喜歡EntLib緩存應用程序塊),而不是複雜的緩存刷新。 – boj 2010-11-12 20:09:04