2012-03-23 7 views
6

Sto utilizzando il nuovo Universal Providers da Microsoft per la sessione in SQL Server. La vecchia implementazione della sessione su SQL Server richiedeva un lavoro (in esecuzione ogni minuto) per cancellare le sessioni scadute. Il nuovo fa questo controllo e cancella ogni richiesta. Poiché in realtà sto eseguendo in SQL Azure, non ho SQL Agent per pianificare i lavori, quindi questo suona come un modo ragionevole per farlo (no, non voglio pagare per Azure Cache per la sessione).OptimisticConcurrencyException con System.Web.Providers

Il problema è quando più utenti accedono al sito contemporaneamente, stanno entrambi tentando di cancellare le stesse sessioni scadute contemporaneamente e il secondo ottiene un'eccezionale eccezione di concorrenza.

System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. 
    at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) 
    at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) 
    at System.Web.Providers.DefaultSessionStateProvider.PurgeExpiredSessions() 
    at System.Web.Providers.DefaultSessionStateProvider.PurgeIfNeeded() 
    at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData) 
    at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Sto utilizzando ELMAH per la registrazione degli errori e questo si sta visualizzando con una certa frequenza. Prima che provi a configurare ELMAH per ignorare gli errori, qualcuno sa in che modo fermare gli errori in primo luogo? C'è qualche configurazione con i nuovi provider che mi manca?

+0

Anche io sto vivendo lo stesso problema. Hai scoperto come risolvere questo problema? L'unico modo che posso pensare è di decompilare il codice? Qualsiasi suggerimento – chugh97

+2

Il meglio che posso dire, Microsoft non supporta realmente questi provider. Il cinico in me dice che stanno cercando di spingere gli utenti di Azure a pagare per la cache. Mi piacerebbe che qualcuno mi dimostrasse che non sbaglio. Alla fine, ci siamo arresi e siamo tornati a un provider SQL Server diretto. Avevamo già bisogno di un altro server per la pianificazione di altri lavori non collegati, quindi abbiamo inserito il lavoro delle sessioni scadute di compensazione anche lì. Scusa, non ho niente di meglio da segnalare. – icrf

+0

Hai risolto questo problema? Sto correndo lo stesso problema io stesso. – onit

risposta

1

Questo pacchetto ha un errore che descriverò. La premessa dello stato della sessione fuori processo è che più istanze potrebbero gestire la pulizia dello stato della sessione. In questo caso tutte le istanze sono in esecuzione questo metodo ...

private void PurgeExpiredSessions() 
{ 
    using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString)) 
    { 
     foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities)) 
     { 
      entities.DeleteObject(entity); 
     } 
     entities.SaveChanges(); 
     this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks; 
    } 
} 

Il problema è che un caso elimina le entità prima che l'altro (s) e le entità genera l'errore descritto nel post. Ho chiesto il pacchetto autori di rilasciare il codice sorgente o risolvere questo problema .. Il mio testo non testato editor di correzione sarebbe quella di aggiungere pubblico virtuale, in modo si potrebbe sovrascrivere il metodo o semplicemente cambiare troppo ..

private void PurgeExpiredSessions() 
{ 
    using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString)) 
    { 
     var sqlCommand = @"DELETE dbo.Sessions WHERE Expires < GETUTCDATE()"; 
     entities.ExecuteStoreCommand(sqlCommand); 
     this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks; 
    } 
} 

Gli autori del pacchetto sono molto veloci con una risposta (risposta durante la pubblicazione di questo!) e oggi hanno dichiarato che stanno lavorando per rilasciare il codice ma che potrebbero essere in grado di risolvere questo problema. Ho richiesto un ETA e proverò a seguire qui se ne ottengo uno.

Ottimo pacchetto, richiede solo un po 'di manutenzione.

Risposta corretta: attendere il rilascio del codice sorgente o un aggiornamento di correzione. Oppure decompilalo e risolvilo da solo (se questo è coerente con la licenza!)

* Aggiorna i proprietari del pacchetto stanno valutando di ripararlo questa settimana. Si! * * Update.SOLVED !!! Evidentemente lo hanno risolto tempo fa e stavo installando il pacchetto sbagliato .. Stavo usando http://nuget.org/packages/System.Web.Providers e avrei dovuto usare http://nuget.org/packages/Microsoft.AspNet.Providers/ .. Non era ovvio per me quale fosse legacy e incluso in un altro pacchetto. L'hanno avvolto in una presa vuota ..

private void PurgeExpiredSessions() 
{ 
    try 
    { 
     using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString)) 
     { 
      foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities)) 
      { 
       entities.DeleteObject(entity); 
      } 
      entities.SaveChanges(); 
      this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks; 
     } 
    } 
    catch 
    { 
    } 
} 

Grazie al team del pacchetto per risposte rapide e un ottimo supporto !!!

+0

** Aggiornamento. Abbiamo provato questo in Azure con circa 250 utenti simultanei e SQL Azure ci ha dato messaggi di errore che indicavano che la macchina fisica non poteva accettare altre connessioni anche se eravamo all'interno del limite di connessione consentito. Il mio verdetto è di evitare questo tipo di gestione delle sessioni in Azure. A proposito, l'unica ragione per cui abbiamo provato questo era perché il nostro attuale sostenitore dello stato di sessione, Azure Caching, aveva troppi interruzioni. – TheDev6

2

Si prega di scaricare la versione più recente dei provider che può essere trovato qui: http://www.nuget.org/packages/System.Web.Providers. Abbiamo aggiornato il modo in cui puliamo le sessioni scadute per l'esecuzione in modo asincrono e per gestire le condizioni di errore. Fateci sapere se non risolve i vostri problemi.

+0

Grazie per l'aggiornamento. Proverò a dare un'occhiata a questa settimana o all'inizio del prossimo progetto. C'è qualche tipo di registro delle modifiche pubbliche disponibile? Mentre spostavo Session lontano dai provider predefiniti, utilizzo ancora Membership/Ruoli. – icrf

+0

L'ho contrassegnato come soluzione, ma non ho provato a verificare se effettivamente risolve il problema. Ci siamo spostati su Azure Caching Preview per Session, quindi testare questo non è più fattibile per me. – icrf

+0

Ho lo stesso identico problema con Sql Azure e l'ultimo nuget di giugno 2012. Nel mio caso sto evadendo la memorizzazione nella cache di azure co localizzata perché ha causato diverse interruzioni dovute a problemi di archiviazione (gestore dello stato della cache) e nuove istanze che non aggiornavano le istanze dipendenti di un nuovo indirizzo IP (l'azzurro ha molti punti di errore sconosciuti). Scott, questo pacchetto di Universal Provider è fantastico! Qualunque follow-up sull'errore però? Sembrerebbe che una delle due istanze in azzurro superi l'altra a PurgeExpiredSessions(). – TheDev6

1

Ho inviato una domanda al NuGet (http://www.nuget.org/packages/System.Web.Providers) e ho ricevuto una risposta molto rapida dai proprietari. Dopo un po 'di backwards e forward, risulta che hanno una soluzione per questo, ma uscirà nel prossimo aggiornamento.

C'è stato un suggerimento qui, che Microsoft non è troppo entusiasta di supportare questo, ma la mia esperienza è stata diversa, e ho sempre ricevuto un buon supporto.

+0

Con "posta una domanda" intendi "contattato il proprietario del pacchetto" oppure esiste un altro metodo per pubblicare domande su NuGet? Molti altri progetti Microsoft sono su Codeplex o Google Code o Github e hanno tutti tracker di problemi e sistemi di discussione. Non sono riuscito a trovare questo progetto da nessuna parte per una discussione aperta. – icrf