2010-11-11 12 views
5

Problema

Abbiamo un modello di dominio complesso. Per evitare problemi di prestazioni, la maggior parte dell'elenco (generato da oggetti dominio) viene memorizzato nella cache. Tutto funziona bene fino a quando il primo oggetto dominio non cambia. Tutti gli elenchi dipendenti nella cache devono essere aggiornati: la domanda è: come?Modifiche agli oggetti di dominio: aggiornamento sugli elenchi in cache necessari

Esempio

  • oggetto Dominio: Casa
  • Azione: Nome di una casa è stato cambiato
  • Effetto: tutti i nomi (containts casa) Lista sono out-of data, aggiornamento necessario

Soluzioni

Senza dubbio, c'è un modo molto semplice: dopo aver salvato un oggetto dominio, aggiorniamo manualmente tutti gli elenchi dal codice.

pseudo codice

repository.Save(save); 

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

Quindi il problema è: dobbiamo aggiornare tutto manualmente. Sto cercando le soluzioni migliori, diciamo:

  • Aspect modo orientato w/PostSharp o Windsor
  • Observer o tecnica basata evento
  • CQRS si tratta di separare le query ei comandi, ma questa concezione è forse troppo tanto.

Qualche idea o esperienza?

risposta

1

La risposta a questa domanda è complessa perché le vostre esigenze non sono chiare. I dati possono essere obsoleti? Se sì, per quanto tempo?

In base alle informazioni limitate nel tuo post, suggerirei le visualizzazioni "memorizzate nella cache" semplicemente come una query sui dati reali. Le stesse query possono aggiornare periodicamente i risultati memorizzati nella cache con un certo intervallo.

+0

Buone domande di follow-up. –

+0

"I dati possono essere obsoleti? Se sì, per quanto tempo?": Forse 1 ora, forse 1 anno. Il problema principale deriva da un dominio aziendale volatile. – boj

0

Direi che, se il tuo inserimento/aggiornamento/cancellazione modifica il contenuto di uno di questi elenchi, dovresti richiedere l'elenco. Ho alcuni dati della cache nella mia app, e io uso una raccolta della struttura sottostante per mantenerli. In questo modo, è facile svuotare l'intera cache, e quando chiedo un particolare datatable controllo per vedere se ne esiste uno nella cache che non è scaduto.

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) 

Questi vivono nella mia classe base per oggetti che interrogano i database. Un esempio di utilizzo delle datatables cache è:

<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 

Nell'esempio precedente, la funzione controlla la cache per vedere se esiste un oggetto appropriato. Se lo fa, viene restituito piuttosto che colpire nuovamente il database. Alla fine, l'oggetto fresco viene aggiunto alla cache.

Tutto quello che dovresti fare sarebbe fornire dei mezzi per rimuovere un particolare elenco dalla cache. Quindi, quando si esegue un inserimento/aggiornamento/eliminazione, assicurarsi di cancellare l'elemento appropriato.

+0

Mi spiace che il codice sia in VB, piuttosto che in C#. http://www.developerfusion.com/tools/convert/csharp-to-vb/ lo converte per te, se si tratta di una soluzione dal suono appropriato. –

+0

Grazie, ma si tratta solo di memorizzazione nella cache (io preferisco EntLib Cache Application Block) e non di un aggiornamento della cache complesso. – boj

Problemi correlati