Substituindo a session do ASP.Net completamente

Sessão ASP.Net parece perfeito para um aplicativo WebForms tradicional, mas eles fazem algumas coisas que são um problema sério para um aplicativo moderno AJAX e MVC.

Especificamente, existem apenas 3 maneiras de acessar o provedor ASP.Net:

  1. Bloquear leitura e gravação (padrão) – a session é bloqueada do acionamento AcquireRequestState até que o ReleaseRequestState triggersdo. Se 3 solicitações ocorrerem no navegador ao mesmo tempo, elas serão enfileiradas no servidor. Esta é a única opção no MVC 2, mas o MVC 3 permite …

  2. Somente leitura sem bloqueio – a session não está bloqueada, mas não pode ser salva. Isso parece não ser confiável , já que algumas leituras parecem bloquear a session novamente.

  3. Sessão desativada – qualquer tentativa de ler ou gravar na session lança uma exceção.

No entanto, com um aplicativo MVC moderno, tenho vários events AJAX acontecendo ao mesmo tempo – não quero a fila no servidor, mas desejo que eles gravem na session.

O que eu quero é um quarto modo: leitura suja, última gravação ganha

Eu acho (feliz de ser corrigido) que a única maneira de fazer isso é replace completamente as sessões do ASP.Net. Eu posso escrever meu próprio provedor , mas ASP ainda vai chamá-lo com um dos três padrões que ele suporta. Existe alguma maneira de fazer a concorrência otimista apoio ASP.Net?

Isso me deixa substituindo todas as chamadas para a session por uma nova class que basicamente faz a mesma coisa, mas não bloqueia – o que é uma dor.

Eu quero manter o máximo de coisas da session atual que eu puder (mais significativamente IDs de session em vários logs) com a quantidade mínima de substituição de código. Há alguma maneira de fazer isso? Idealmente, eu gostaria que o HttpContext.Current.Session para a minha nova class, mas sem o ASP.Net bloquear quaisquer solicitações.

Alguém já fez algo assim? Parece estranho que com todos os aplicativos AJAXey MVC lá fora, este é um novo problema com o ASP.

Primeiro de tudo eu digo que MS asp.net tem bloqueio no núcleo do “asp.net processamento de uma página” a session, em algum lugar no dll ” webengine4.dll ” para asp.net 4

E eu digo que a partir do ponto de vista do MS asp.net act correct and lock the session this way porque o asp.net não pode saber que tipo de informação mantemos na session para que possa fazer uma correta “última gravação ganha”.

Também correto é o bloqueio para a session da página inteira, pois dessa forma é dada a sua uma synchronization muito importante do seu programa, que por experiência agora eu digo que você precisa dela para a maioria de suas ações. Depois de ter substituído a session ms com a minha, em todas as minhas ações eu preciso fazer um bloqueio global, ou então eu tenho problemas com inserções duplas, ações duplas, etc.

Eu dou um exemplo da questão que reconheço aqui. Os dados da session são salvos em SessionSateItemCollection, que é uma lista de chaves. Quando a session lê ou escreve esta coleção é fazer todos eles juntos. Então vamos ver este caso.

temos variables ​​de tree na session, “VAR1”, “VAR2”, “VAR3”

Página 1.
getsession (na verdade, obter todos os dados e colocá-los na lista)
session [VAR1] = “data1”;
savesession ()
O resultado é VAR1 = data1, VAR2 = (último dado de var2), VAR3 = (último dado de var3)

Página 2.
getsession (na verdade, obter todos os dados e colocá-los na lista)
session [VAR2] = “data2”;
savesession ()
O resultado é VAR1 = (último dado de var1), VAR2 = dado2, VAR3 = (último dado de var3)

Página 3.
getsession (na verdade, obter todos os dados e colocá-los na lista)
session [VAR3] = “data3”;
savesession ()
O resultado é VAR1 = (último dado de var1), VAR2 = (último dado de var2) VAR3 = “dado3”

Note aqui que cada página tem um clone dos dados, enquanto os lê a partir do meio da session (por exemplo, como eles leram pela última vez no database)

Se deixarmos estas 3 páginas rodarem sem travar, não teremos leitura realmente suja, nem “últimas vitórias de escrita” – O que temos aqui é ” a última gravação destrói as outras “, porque se você pensar de novo, quando a VAR1 mudar , porque o VAR2 e o VAR3 permanecem os mesmos? E se você tiver mudado VAR2 em outro lugar.

e por esse motivo não podemos deixar isso sem bloqueio como é.

E agora imaginando isso com 20 variables ​​… totalmente bagunça.

Soluções possíveis

Por causa do multithread do asp.net de muitos pools, a única maneira de manter os mesmos dados em pools e em computadores é ter um database comum ou um programa de processo comum, como o asp.net State Service.

Eu escolhi ter um database comum como mais fácil do que criar um programa para essa proposta.

Agora, se conectarmos um cookie que fizermos, ao usuário ao usuário de dados da session , e controlarmos os dados usando um campo de database totalmente personalizado, saberemos o que gostamos de bloquear, o que não, como salvar ou alterar, ou comparar e manter a última gravação ganha dados, podemos fazer isso funcionar e desativar totalmente a session asp.net que é um gerenciador de session genérico feito para todas as necessidades, mas não feito para lidar com casos especiais como este.

Pode asp.net fazer este trabalho no futuro lançamento, sim, ele pode, fazendo um campo extra chamado sujo, e na session salvar dados, fazer uma mesclagem de dados usando o campo sujo, ou algo parecido, mas não pode fazer isso agora trabalhe como está – pelo menos do que eu encontrei até agora.
Na verdade SessionStateItem tem um sinalizador sujo nas propriedades, mas não fez essa mesclagem no final de salvar dados. Eu realmente vou amar se alguém pensar em uma solução para o ms existente asp.net session estado goleiro, estou escrever o que eu encontrei até agora, mas isso não significa que, com certeza, não há nenhuma maneira – eu não tenho achei como é.

Espero que tudo ajude 🙂

SessionStateModule personalizado

nesta resposta https://stackoverflow.com/a/3660837/159270 o James depois de escrever um módulo personalizado diz: Eu ainda não consigo acreditar que a implementação personalizada da Sessão ASP.Net bloqueia a session para toda a solicitação.