sugerencia con la cache
-
2012年7月23日 下午 08:44
hola...
este es mi caso:
tengo una aplicacion web desarrollada con .net mvc3 y se utiliza un monton de jquery y
un monton de peticiones ajax a mi base de datos, estas peticiones lo que hacen
es llenar combos cajas de texto y cosas asi como cualquier otra aplicacion,
pero mi duda es como podria utilizar la cache para no estar aciendo tantas peticiones
a mi base de datos si estas ya estan cargadas en la cache. alguien tendra alguna sugerencia con el tema
¿es posible utilizar la cache?jose arreola
所有回覆
-
2012年7月23日 下午 11:07版主
En programación multicapas usted tendría una colección que se llena una vez y se reutiliza constantemente. Suele estar en una clase estática y la colección sería también estática. Como las páginas web son multiusuario, la colección debe sincronizarse.
//Clase no estática en la capa de datos con colección estática. //Ejemplo que carga objetos Region que rara vez cambian. public class Region { #region Miembros estáticos private static List<Region> m_regiones; private object _sync = new object(); public static List<Region> Regiones { get { lock (_sync) { if (m_regiones == null) { //Solicitarle a la capa de datos (base de datos) //la lista de regiones aquí. //Luego llenar la colección m_regiones. } //Devolver una copia: return new List<Region>(m_regiones); } } } #endregion #region Propiedades public int ID { get; protected set; } public string Nombre { get; protected set; } #endregion #region Constructores public Region(int id, string nombre) { ID = id; Nombre = nombre; } #endregion }
En el ejemplo se asume que hay una lista de regiones que cambia muy poco, así que la cargamos una única vez (la primera vez que se necesita) y luego nada más devolvemos copias sin tener que consultar la base de datos nuevamente.
Jose R. MCP
Code Samples- 已標示為解答 ch-B 2012年7月25日 下午 03:11
-
2012年7月25日 上午 06:17
Concuerdo con WebJose en que la solución consiste en que las peticiones enviadas en modo AJAX desde el cliente atraviesen una clase que se encargue de guardar los resultados en caché, y devolverlos en cada petición sucesiva sin realizar una nueva consulta a la base de datos.
Pero opino que en lugar de usar una variable estática, es preferible usar el objeto Cache. La ventaja es que en caso de que aumente la presión de memoria sobre el servidor, el Cache descarta automáticamente los datos cacheados menos necesarios, y libera esa memoria para otros usos más importantes. También se le puede configurar una expiración automática para que los datos se actualicen desde la base de datos a la memoria con determinada periodicidad. En suma, en lugar de usar la variable estática el código quedaría así:
public static List<Region> Regiones
{
get
{
List<Region> r = Cache["Regiones"] as List<Region>;
if (r==null)
{
r=(sacar datos de la BD)
Cache.Insert("Regiones", r, ...opciones...);
}
return r;
}
}Nótese que he omitido el lock. En caso de que dos hilos entrasen a la rutina simultáneamente, y los dos encontrasen el Cache vacío, se recuperarían los datos dos veces desde la base de datos. La probabilidad de que esto ocurra es lo suficientemente pequeña para que esta recuperación adicional sea en promedio menos costosa que la ejecución del lock a cada llamada para obtener datos. La lectura e inserción en el Cache no necesitan bloqueo en el código que las llama porque internamente son seguras en cuanto al acceso en multihilo.
- 已標示為解答 ch-B 2012年7月25日 下午 03:11
-
2012年7月25日 上午 06:46版主
Sí, la clase System.Web.Caching.Cache es bien interesante y útil. El detalle es que está ligada a System.Web entonces no suelo ni acordarme que existe ya que yo suelo proveer el cache en la capa de negocio o datos según lo necesite. Esta clase está muy ligada a la capa gráfica y es lo que no me gusta.
Pero en fin, sí es cierto que tiene todas las ventajas que Alberto menciona, y si no tiene usted inconveniente en mantener el cache en la capa gráfica, pues adelante que le trabajará muy bien según lo menciona Alberto.
Sí debo mencionar que me parece muy interesante su último párrafo acerca de la sincronización de hilos. Sería genial si hubiera alguna experimentación documentada al respecto, pues suelo ser bastante estricto en cuanto a sincronizar siempre que deba hacerse.
ACTUALIZACIÓN: MSDN dice que la clase es thread-safe. Así que podemos obviar el comentario último de mi parte, pues el uso del lock es casi irrelevante. Sí, sería igual bonito ver si hay tiempos documentados, pero por lo menos me queda claro que la sincronización ya se da internamente.
Jose R. MCP
Code Samples- 已編輯 webJoseMicrosoft Community Contributor, Moderator 2012年7月25日 上午 06:49
-
2012年7月25日 上午 07:27
El truco para usar la Cache desde la capa de negocio o de datos es añadir una referencia a System.Web.dll, y llamar al cache como HttpContext.Current.Cache. Esto sólo funciona si dicha capa de negocios o de datos se va a usar exclusivamente desde aplicaciones web; si se llamara a la misma DLL desde una aplicación de escritorio, HttpContext.Current devolvería null.

