asp.net mvc - sesiones - ¿Existe una mejor práctica y una alternativa recomendada para las variables de sesión en MVC?
variables de session mvc 5 (3)
Cuando
Las bases de datos están altamente optimizadas. Un valor simple como el conteo de un carrito de compras es un buen candidato para el almacenamiento en caché de la base de datos y (con suerte) es económico para calcular directamente. Puede ser un no problema.
Sin embargo, si ha descartado otros mecanismos, los valores pequeños de usuario por usuario son candidatos viables para la sesión.
Cache
está bien para valores de todo el sitio, o valores específicos del usuario con claves únicas. Sin embargo, la sincronización de cachés en múltiples servidores web puede ser difícil. El estado de la sesión fuera de proceso permanecerá sincronizado porque está almacenado en una sola ubicación (base de datos o servidor de estado).
Por supuesto, hay muchas alternativas de almacenamiento en caché de terceros con varias opciones para mantenerlas sincronizadas.
Independientemente de dónde se almacene temporalmente el recuento, soy de la opinión de que los propios carritos de compras deben almacenarse en la base de datos para que los usuarios tengan la opción de regresar más tarde y continuar donde lo dejaron.
Actuación
Si utiliza un estado de sesión fuera de proceso (por ejemplo, en un entorno equilibrado de carga y / o para hacer la sesión más duradera), golpeará una base de datos o llamará a un servicio fuera de proceso, pero la llamada es relativamente barata a menos que serialice un objeto grande gráficos
La sesión se carga una vez por solicitud. El acceso de lectura posterior es muy rápido.
Escribir una sesión puede ser perjudicial para el rendimiento, incluso cuando no hay carga. ¿Por qué? la mayoría de las aplicaciones modernas usan llamadas asíncronas, y cuando múltiples llamadas asincrónicas golpean un manejador HTTP (página, controlador, etc.) que lee / escribe sesión, ASP.Net bloqueará la sesión para serializar el acceso. Para evitar esto, puede decorar sus controladores con [SessionState( SessionStateBehavior.ReadOnly )]
Diseño
Ahora he logrado con éxito esta tarea asignando el valor a una variable de sesión que se recupera de mi vista de distribución;
Esto parece una mezcla de preocupaciones, es decir, tener la vista al tanto del mecanismo de almacenamiento subyacente. Desde un punto de vista purista, establecería este valor en un modelo de vista o al menos lo pondría en el ViewBag
. Desde un punto de vista práctico, uno o dos valores recuperados de esta manera probablemente no dañarán nada, pero tengan cuidado de dejar que crezca mucho más.
Leí en alguna parte el uso de filtros MVC en conjunto con la sección de inicio de la aplicación Global.ascx también, pero esto no parece apropiado para las variables establecidas en el nivel de controlador tanto como quizás variables estáticas.
Las variables estáticas tienen usos perfectamente legítimos, pero debe comprenderlas a fondo o arriesgarse a problemas graves.
Ver mis respuestas relacionadas con variables estáticas en ASP.Net:
Bien, primero, antes de que alguien intente tomar una determinación de que esta es una pregunta "duplicada"; He revisado la mayoría de las publicaciones sobre SO con respecto a preguntas similares, pero incluso en combinación de todo lo que se ha dicho, todavía estoy en un dilema en cuanto al acuerdo definitivo o quizás debería decir unánime al respecto.
Sin embargo, puedo decir que (según las publicaciones) he determinado de manera concluyente que la respuesta se basa en el alcance del requisito. Pero aun teniendo esto en cuenta, las opiniones parecen demasiado diversas como para tomar una decisión sobre cómo debo manejar esto.
Mi requerimiento inmediato es que necesito persistir datos variables de 1 controlador en muchas vistas. Más específicamente, tengo un controlador y una vista correspondiente que maneja los conteos de ítems del carrito de compras y me gustaría persistir esa información en múltiples vistas. Estoy pensando que la vista _layout es la opción más lógica para esto.
Ahora he logrado con éxito esta tarea asignando el valor a una variable de sesión que se recupera de mi vista de distribución; por lo tanto, incluso cuando el usuario navegue en cualquier lugar dentro del sitio, la cantidad de elementos en el carrito de la compra persistirá hasta que salga del sitio o complete el proceso de pago; en cuyo caso la variable se borrará en el código.
Las publicaciones que he leído parecían sesgadas por mantenerse alejado de las variables de Sesión a favor de las Cookies y el almacenamiento de datos en una base de datos; o indicando que para el propósito de intención para el que propongo usarlos, las variables de Sesión están perfectamente bien de usar.
La otra cosa que he leído sugiere que las variables de sesión pueden impedir el rendimiento general si hay mucho tráfico en el sitio, ya que la información se almacena en el servidor.
Personalmente, no puedo justificar el almacenamiento de este tipo de información en una base de datos y, luego, acceder a la base de datos, ya que supongo que esto también podría afectar el rendimiento del sitio y parece un poco exagerado para el almacenamiento de datos temporales. TempData, ViewData y ViewBag no funcionan para persistir en los datos, por lo que no son opciones lógicas para el requisito IMO.
Si hay otra alternativa adecuada para la variable Session (que funciona para mí), me gustaría saber de qué se trata.
2 publicaciones que parecen contradictorias en el esfuerzo por brindar las mejores recomendaciones me dejan un poco confundido.
Contras: ¿es una buena práctica evitar el uso del estado de sesión en ASP.NET MVC? Si es así, ¿por qué y cómo?
Parece que esta pregunta (aunque presentada en muchas variaciones diferentes) no tiene una respuesta definitiva que pueda concluir.
Si hay una manera más preferible de lograr esto sin overkill, esa es la respuesta que estoy buscando.
Leí en alguna parte el uso de filtros MVC en conjunto con la sección de inicio de la aplicación Global.ascx también, pero esto no parece apropiado para las variables establecidas en el nivel de controlador tanto como quizás variables estáticas.
¿Alguien puede aplastar (a falta de una palabra mejor) las diversas opiniones sobre el tema y quizás brindar una respuesta más definitiva a la pregunta? Estoy seguro de que las diversas opiniones tienen su lugar y no estoy tratando de desacreditarlas. Pero tener una respuesta definitiva y posiblemente unánime sería mejor; luego podría ordenar las otras publicaciones para determinar qué es lo mejor para mi aplicación.
Por supuesto, si esta pregunta no tiene una respuesta definitiva; solo dímelo e intentaré derivar mi propia respuesta de las otras publicaciones.
Gracias
=============================================== =========
RESPUESTA ACTUALIZADA A RESPUESTAS PROPORCIONADAS
El almacenamiento en caché y las cookies parecen ser una preferencia general de las respuestas; sin embargo, también he notado la afirmación de que el almacenamiento en caché no es un candidato ideal para usar en múltiples servidores web porque la sincronización puede ser un problema potencial.
Al darle crédito a Tim, se afirma que el almacenamiento de la base de datos está optimizado y los usuarios tienen la opción de regresar más adelante y continuar donde lo dejaron.
Ese es un punto excelente, pero manteniendo la previsión de las probabilidades; Es probable que sea razonable dado que algunos usuarios pueden no regresar dejando datos innecesarios en la base de datos.
Por lo tanto, mantener el DB optimizado y limpio (que "para mí" tiene la misma relevancia) requeriría implementar una tarea de mantenimiento para caducar automáticamente esos registros en función de un umbral de tiempo establecido para dar cuenta de esas circunstancias. Aunque una tarea de mantenimiento no es una opción incuestionable, todavía creo que esto agrega un poco más de trabajo a la tarea simplemente con el propósito de servir como almacenamiento temporal.
No obstante, respeto la recomendación de Tim y creo que merece mérito al contrarrestar mi opinión inicial hasta cierto punto; que una base de datos no parece ser una opción viable para almacenar datos temporales; así que creo que el compromiso sería almacenar los datos en una base de datos (dada la situación de un Carrito de Compras o similar) tal vez después de un pago. De esta forma, como indicó anteriormente, los datos pueden rastrearse de manera persistente en visitas posteriores, de modo que tenga un registro de las transacciones. Pero lo más importante es que los datos de esas transacciones que tengan una relevancia real persistan en la base de datos.
También se afirmó que aunque Session es más rápido que Database; pero a pesar de tener sus salvedades que pueden ser mitigadas hasta cierto punto por otros mecanismos, tales como aprovechar el atributo SessionStateBehavior, solo sirviendo como un ejemplo.
PERO ... Creo que Erik llevó el punto a casa con el efecto Dunning-Kruger. Aunque, a partir del contenido y las explicaciones para las respuestas propuestas dadas aquí; Dudo seriamente que la experiencia de cualquiera de las personas que han respondido sea cuestionable. Sin embargo, tiendo a estar de acuerdo en el hecho de que obtener una opinión unánime puede ser algo más que una expectativa razonable de mi parte.
Lo que buscaba más específicamente era un consenso general para una técnica que pudiera acomodarse cómodamente a una diversidad de escenarios. En otras palabras, algo que se acomodaría no solo a mi escenario particular sino que también proporcionaría el elemento de escalabilidad a entornos más grandes con tráfico potencialmente más pesado. De esta forma, un cambio en la programación sería aliviado por completo o mínimo en el mejor de los casos.
===============================================
Resumen basado en los comentarios:
Las variables de sesión parecen acomodar escenarios de casos más pequeños y, cuando corresponde, pero tienen cierto potencial para problemas de persistencia, entre otras discrepancias notables, tal como lo afirma Erik. Entonces esta opción obviamente no se ajustará a un modelo escalable.
El almacenamiento en caché es preferible a las variables de Sesión pero, una vez más, no es la "mejor" opción escalable debido, entre otras cosas, a las posibles complejidades de sincronización en los entornos de servidores de servidores web, como se señaló anteriormente. Pero una opción, no obstante.
El almacenamiento de la base de datos es escalable, pero con el propósito de almacenamiento temporal volátil probablemente no sea la opción más elegante desde la perspectiva de una base de datos, ya que requeriría una limpieza periódica. Personalmente, tener una base sólida en conceptos de bases de datos al principio de mi carrera, probablemente no sea algo con lo que muchos desarrolladores probablemente estén de acuerdo; pero usar la base de datos para este propósito puede ser suficiente para el Desarrollo Web desde la perspectiva de los programadores; sin embargo, desde la perspectiva del desarrollo de DAL y DB, esto (para mí) tiene el potencial de obligar a una tarea DB adicional a imponer un back-end eficiente.
Las cookies parecen ser una buena opción con los elementos combinados "deseables" de las variables de sesión y el almacenamiento en caché.
===============================================
CONCLUSIÓN
Basado en las respuestas; Creo que COOKIES y CACHING parecen ser, en general, propuestas bien redondeadas para las mejores prácticas en general, en combinación con el almacenamiento de la base de datos cuando se requiere persistencia continua después del hecho; como candidatos potencialmente buenos para la escalabilidad de los presentados.
La última elección entre los 2 parecería basarse en la cantidad y el tipo de datos que requieren almacenamiento (por ejemplo, sensible frente a no sensible y si existe o no la preocupación de que el cliente pueda alterar los datos en su extremo); además de consideraciones especiales para COOKIES en el hecho de que pueden ser deshabilitados por los clientes.
Obviamente, no existe una solución única para todos, como se señala claramente y se concluye a partir de las respuestas proporcionadas, pero en términos de escalabilidad; Puedo estar equivocado, pero estas parecen ser las MEJORES opciones disponibles.
Porque todas las respuestas son buenas; Voy a acreditar todas las publicaciones como útiles y voy a aceptar la respuesta de Erik como una solución escalable global y escalable. Desearía poder seleccionar más de una respuesta aceptada ya que creo que la respuesta de Tim también estuvo muy bien explicada.
La respuesta de Gupta también fue buena, pero quería más elaboración de la respuesta propuesta y no una repetición de publicaciones anteriores.
¡Gracias chicos!
Nunca obtendrá una opinión unánime sobre nada en ningún grupo grande de personas. Eso es solo naturaleza humana. Parte de eso se deriva del efecto Dunning-Kruger, que establece que cuanto menos sepa alguien sobre un tema, más probable es que valore más su experiencia en ese tema. En otras palabras, muchas personas piensan que saben algo, pero solo porque no saben que no lo saben. Parte de esto es simplemente que la gente tiene experiencias diferentes, y algunos no han encontrado problemas con la sesión, mientras que otros lo han hecho en diversas situaciones, o viceversa ...
Por lo tanto, para respaldar su investigación, que sugiere que la respuesta depende en gran medida de los requisitos, debemos entender cuáles son sus requisitos. Si se trata de un sitio de alto tráfico, con servidores con equilibrio de carga en una granja de servidores web, manténgase tan alejado de la sesión como pueda. Claro, es posible compartir sesiones de varias maneras en un entorno de granja de servidores (servidor de sesión, distribuir el servidor de caché, etc.), pero evitar la sesión casi siempre será más rápido si puede ayudarlo.
Si su sitio es un único servidor, es poco probable que crezca más allá de eso. Y sus patrones de tráfico son relativamente bajos, entonces la sesión puede ser una opción útil. Sin embargo, siempre debe tener en cuenta que la sesión no es confiable y puede desaparecer en cualquier momento. Si el grupo de aplicaciones se recicla, la sesión se ha ido. Si una excepción no detectada surge durante el proceso de trabajo, la sesión puede haber desaparecido. Si IIS cree que no hay suficiente memoria, es posible que su sesión se haya ido, independientemente de los valores de tiempo de espera configurados. Tampoco siempre se puede obtener una notificación confiable de que una sesión ha finalizado, ya que las sesiones terminadas no activan el evento Session_End.
Otro problema es que la sesión está serializada. En otras palabras, IIS evita que más de un hilo escriba en la sesión a la vez, y a menudo lo hace bloqueando la sesión mientras se está ejecutando un hilo si no se ha excluido del bloqueo de sesiones de escritura. Esto puede causar problemas graves en algunos casos, y simplemente un rendimiento deficiente en otros. Puede mitigar esto marcando varios métodos con un atributo de sesión de solo lectura si no va a modificarlo en ese método.
En última instancia, si decide usar la sesión, intente usarla solo para cosas pequeñas y breves si es posible, y si no es posible, compile de forma que "regenere" los datos si la sesión se pierde. Por ejemplo, si usa su número de elementos en el ejemplo de carro, podría escribir un método que primero verifique si el valor está allí y, si no, lo va a cargar desde la base de datos. Utilice siempre este método para acceder a la variable, en lugar de acceder a ella directamente desde la sesión ... de esta manera, si la sesión se pierde, simplemente la volverá a cargar.
Sin embargo, habiendo dicho esto ... Para la cantidad de artículos en un carrito, generalmente preferiría usar una cookie para esta información, ya que las cookies pasan a la página en cada carga de todos modos, y esta es una pequeña unidad discreta de datos. . En general, prefiere la sesión para los datos confidenciales que desea evitar que el usuario pueda cambiar. El número de elementos en el carro simplemente no se ajusta a esa regla.
Sesión alternativa en diferentes prospectos: -
Cuando mantiene algo en sesión, rompe la regla primaria en ASP.NET MVC. Puede usar estas opciones como una alternativa de sesión.
Si su sesión de asp.net (MVC) hace boxeo unboxing en el objeto, entonces hace una pequeña carga en el servidor. Prueba esta idea
Almacenamiento en caché: - Almacenar una lista o algo así como datos grandes en la sesión es mejor, puede caber en el almacenamiento en caché. Usted tiene el control cuando quiera que caduque en lugar de la sesión del usuario.
Si su aplicación depende de datos JSON / Ajax, puede utilizar algún tipo de funcionalidad proporcionada en html5 (como WebSQL, IndexDB). no usará la cookie para que pueda guardar alguna carga de trabajo en el servidor.