Reemplazando la sesión de ASP.Net por completo
session concurrency (1)
La sesión de ASP.Net parece perfecta para una aplicación tradicional de WebForms, pero hacen algunas cosas que son un problema grave para una aplicación moderna AJAX y MVC.
Específicamente, solo hay 3 formas de acceder al proveedor de ASP.Net:
Bloqueo de lectura y escritura (predeterminado): la sesión está bloqueada desde la
AcquireRequestState
deAcquireRequestState
deAcquireRequestState
hasta que seReleaseRequestState
. Si se producen 3 solicitudes desde el navegador, se pondrán en cola en el servidor. Esta es la única opción en MVC 2, pero MVC 3 permite ...Lectura sin bloqueo solo : la sesión no está bloqueada, pero no se puede guardar en. Sin embargo , esto parece no ser confiable , ya que algunas lecturas parecen bloquear nuevamente la sesión.
Sesión deshabilitada : cualquier intento de leer o escribir arroja una excepción.
Sin embargo, con una moderna aplicación MVC, tengo muchos eventos AJAX sucediendo a la vez. No quiero que estén en la cola del servidor, pero sí quiero que puedan escribir en la sesión.
Lo que quiero es un cuarto modo: lectura sucia, la última escritura gana
Creo (feliz de ser corregido) que la única forma de hacerlo es reemplazar por completo las sesiones de ASP.Net. Puedo escribir mi propio proveedor , pero ASP todavía lo llamará con uno de los 3 patrones que admite. ¿Hay alguna forma de hacer que ASP.Net sea compatible con la concurrencia optimista?
Esto me deja reemplazando todas las llamadas a la sesión con una nueva clase que básicamente hace lo mismo, pero no se bloquea, lo cual es un problema.
Quiero mantener todo el material de la sesión actual que pueda (lo más significativo es que identifique las sesiones en varios registros) con la cantidad mínima de reemplazo de código. ¿Hay alguna manera de hacer esto? Lo ideal sería que quisiera que HttpContext.Current.Session
a mi nueva clase pero sin que ASP.Net bloqueara ninguna solicitud.
¿Alguien ha hecho algo como esto? Parece extraño que con todas las aplicaciones AJAXey MVC, este es un nuevo problema con ASP.
En primer lugar, digo que MS asp.net ha bloqueado el núcleo de "asp.net processing a page" la sesión, en algún lugar de la DLL " webengine4.dll " para asp.net 4
Y digo que desde el punto de vista de MS asp.net act correct and lock the session this way
porque asp.net no puede saber qué tipo de información guardamos en la sesión para que pueda hacer una correcta "última escritura gana".
También es correcto bloquear la sesión de la página completa porque de esa manera se obtiene una sincronización muy importante de su programa, que a partir de la experiencia actual digo que la necesita para la mayoría de sus acciones. Después de reemplazar la sesión ms por la mía, en todas mis acciones necesito hacer un bloqueo global, o si no tengo problemas con inserciones dobles, acciones dobles, etc.
Doy un ejemplo del problema que reconozco aquí. Los datos de la sesión se guardan en SessionSateItemCollection, que es una lista de claves. Cuando la sesión lee o escribe esta colección, hágalo todos juntos. Entonces veamos este caso.
tenemos variables de árbol en la sesión, "VAR1", "VAR2", "VAR3"
Página 1.
getession (en realidad obtener todos los datos y colocarlos en la lista)
sesión [VAR1] = "data1";
guardar la sesión()
el resultado es VAR1 = data1, VAR2 = (últimos datos de var2), VAR3 = (últimos datos de var3)
Página 2.
getession (en realidad obtener todos los datos y colocarlos en la lista)
sesión [VAR2] = "data2";
guardar la sesión()
el resultado es VAR1 = (últimos datos de var1), VAR2 = datos2, VAR3 = (últimos datos de var3)
Página 3.
getession (en realidad obtener todos los datos y colocarlos en la lista)
sesión [VAR3] = "data3";
guardar la sesión()
el resultado es VAR1 = (últimos datos de var1), VAR2 = (últimos datos de var2) VAR3 = "data3"
Tenga en cuenta que cada página tiene una clonación de los datos, ya que los leyó desde el medio de la sesión (por ejemplo, la última vez que los leyó de la base de datos)
Si permitimos que estas 3 páginas se ejecuten sin bloqueo, no tenemos realmente lectura sucia, "la última escritura gana" - Lo que tenemos aquí es " la última escritura destruye las otras ", porque si lo piensas de nuevo, cuando VAR1 cambie , ¿por qué el VAR2 y el VAR3 siguen siendo los mismos? ¿Qué pasa si tienes un cambio de VAR2 en otro lugar?
y por esa razón no podemos dejar esto sin bloqueo como está.
Y ahora imaginándolo con 20 variables ... totalmente lío.
Soluciones posibles
Debido a la multiplicidad de asp.net de muchas agrupaciones, la única forma de mantener los mismos datos en las agrupaciones y en las computadoras es tener una base de datos común o un programa común para todos los procesos, como el Servicio estatal asp.net.
Selecciono tener una base de datos común como más fácil que crear un programa para esa propuesta.
Ahora si conectamos una cookie que hacemos, al usuario con el usuario de datos de la sesión , y controlamos los datos usando un campo de base de datos totalmente personalizado que sabemos lo que nos gusta bloquear, qué no, cómo guardar o cambiar, o comparar y conservar los datos de la última escritura ganada, podemos hacer que esto funcione, y deshabilitar por completo la sesión asp.net que es un guardián de sesión genérico hecho para todas las necesidades, pero no para manejar casos especiales como este.
¿Puede asp.net hacer que esto funcione en la versión futura? Sí, puede crear un campo adicional llamado sucio, y en la sesión guardar datos, hacer una combinación de datos usando el campo sucio, o algo así, pero no puede hacer esto ahora funciona como es, al menos por lo que he encontrado hasta ahora.
En realidad, SessionStateItem tiene un indicador sucio en las propiedades, pero no hizo que esta fusión al final de guardar datos. Realmente me encantará que alguien más piense en una solución para el estado actual de la sesión ms asp.net. Escribo lo que he encontrado hasta ahora, pero esto no significa que de seguro no haya forma, no lo he hecho. lo encontré como es.
Espero que todo ayude :)
SessionStateModule personalizado
en esta respuesta, https://.com/a/3660837/159270 el James después de escribir un módulo personalizado dice: Todavía no puedo creer que la implementación personalizada de la sesión ASP.Net bloquee la sesión para toda la solicitud.