Ci sono dubbi sull'utilizzo di un'unità di lavoro statica di sola lettura in modo che si comporti come una cache?

1

Domanda correlata: Come faccio a memorizzare nella cache i dati che raramente cambiano ?

Sto creando un'applicazione ASP.NET MVC4.

Ad ogni richiesta, i dettagli di sicurezza relativi all'utente dovranno essere verificati con l'area / controller / azione a cui stanno accedendo per vedere se sono autorizzati a visualizzarlo. Le informazioni di sicurezza sono memorizzate nel database.

Ad esempio:

User
Permission
UserPermission
Action
ActionPermission

Un "Permesso" è un token che viene applicato a un'azione MVC per indicare che il token è necessario per accedere all'azione. Una volta che l'utente riceve l'autorizzazione (tramite la tabella UserPermission), ha il token e può quindi accedere all'azione.

Ho cercato come memorizzare nella cache questi dati (dato che cambia raramente) in modo che io stia solo interrogando i dati in memoria e non colpendo un database (che al momento è un notevole risultato di prestazioni).

Ho provato a memorizzare elementi negli elenchi, utilizzando un provider di memorizzazione nella cache ma mi imbatto in problemi o le prestazioni non migliorano.

Un problema per cui sono costantemente in esecuzione è che sto usando il caricamento lazy e i proxy dinamici con EntityFramework. Ciò significa che anche se I ToList() tutto e li memorizzo in un posto statico, le relazioni non vengono mai popolate. Ad esempio, User.Permissions è un ICollection ma è sempre nullo. Non voglio Include() tutto perché sto cercando di mantenere le cose semplici e generiche (e facili da modificare).

Una cosa che so è che un DbContext di EntityFramework è un'unità di lavoro che agisce con il caching di primo livello. Cioè, per la durata dell'unità di lavoro, tutto ciò a cui si accede è memorizzato nella cache.

Voglio creare un DbContext di sola lettura che esisterà indefinitamente e sarà usato solo per leggere informazioni sui permessi. Dopo averlo testato, ha funzionato perfettamente; i tempi di caricamento della mia pagina sono passati da 200ms + a 20ms. Posso facilmente forzare i dati per l'aggiornamento a determinati intervalli o semplicemente lasciarlo per aggiornare quando il pool di applicazioni viene riciclato. Fondamentalmente si comporterà come una cache.

Si noti che il resto dell'applicazione interagirà con altri contesti che esistono per richiesta normalmente.

C'è qualche svantaggio in questo approccio? Potrei fare qualcosa di diverso?

    
posta Rowan Freeman 06.12.2013 - 04:15
fonte

1 risposta

3

Sì, ci sono molti problemi con questo approccio.

Innanzitutto, EF DBContext non è thread-safe. Se lo rendi statico, più utenti che colpiscono questo DbContext allo stesso tempo possono causare il danneggiamento dei dati, in particolare se stai salvando qualsiasi elemento nel database. Anche se è di sola lettura, devi ancora fare i conti con il fatto che gli oggetti vengono inseriti nella cache locale in fase di runtime, e anche questo non è sicuro per i thread.

In secondo luogo, DbContexts è progettato per essere di breve durata. Non esiste un meccanismo per la pulizia. Ciò significa che se la tua app viene eseguita per mesi, conterrà questi dati per ogni utente che abbia mai effettuato l'accesso, utilizzando sempre più memoria man mano che procede fino al riavvio del processo di lavoro.

In terzo luogo, dovresti semplicemente memorizzare nella cache i tuoi dati di cui hai bisogno in Asp.NET Cache. Questo ha dei meccanismi per espirare i dati dopo un certo periodo di tempo ed è progettato per affrontare queste situazioni.

    
risposta data 29.05.2014 - 09:26
fonte