开发者

Domain object changes - refresh on cached lists needed

Problem

We have a complex domain model. To avoid performance issues, most of the list (generated from domain objects) are cached. Everything works well until the first domain object changes. All depending list in the cache must be refreshed - the question is: how?

Example

  • Domain object: House
  • Action: Name of a house has been changed
  • Effect: all list (containts house names) are out-of-date, refresh needed

Solutions

No doubt, there is a very easy way: after saving a domain object, we refresh all list from code manually.

Pseudo c开发者_开发百科ode

repository.Save(save);

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

So the problem is: we have to refresh everything manually. I'm looking for better solutions, let's say:

  • Aspect oriented way w/ PostSharp or Windsor
  • Observer or event based technique
  • CQRS it's about separating queries and commands, but this conception is maybe too much.

Any idea or experience?


The answer to this question is complex because your requirements are unclear. Can data be stale? If so, how long?

Based on the limited information in your post, I would suggest the "cached" views merely being a query over the real data. The queries themselves could periodically refresh their cached results given some interval.


I'd say that, if your insert / update / delete modifies the contents of one of those lists, you should requery the list. I've got some cached datatables in my app, and I use a collection of the structure below to maintain them. This way, it's easy to clear the entire cache, and when I ask for a particular datatable I check to see if one exists in the cache which is not expired.

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)

These live in my base class for objects which query databases. An example of using the cached datatables is:

    <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

In the above example, the function checks the cache to see whether an appropriate object exists. If it does, that gets returned rather than hitting the database again. At the end, the fresh object is added to the cache.

All you'd have to do would be to provide some means of removing a particular list from the cache. Then, when you do an insert / update / delete, make sure you clear the appropriate item.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜