Sito ad alto volume che utilizza ADO.NET TransactionScope vs ExecuteCommand su NOLOCK, LEGGI UNCOMMITTED direttamente?

StackOverflow https://stackoverflow.com/questions/628004

Domanda

Ho appena letto questo interessante articolo di Omar sul suo blog Linq to SQL risolve il deadlock delle transazioni e il problema del timeout delle query utilizzando letture non confermate e alla fine Javed Hasan ha iniziato a discutere con lui della sua soluzione alla situazione del nulla in un sito ad alto volume.

Qui, il problema che si tenta di risolvere è che, dal senso sql, dobbiamo usare le istruzioni Select con NOLOCK o usare SET LEVEL TRANSACTION LEGGERE NON COMUNICATO, altrimenti in caso di file ad alto volume nel DB verranno bloccate e causeranno errori. La tecnologia utilizzata da Omar è Linq2Sql, quindi la domanda è: come possiamo ottenere questo risultato nel tuo codice di accesso ai dati C #, quindi quanto sopra non accade?

Fondamentalmente nel post, Omar arriva alla sua soluzione lavorando e testando sul sito del mondo reale e con strumenti come SqlProfiler, mentre Javed Hasan arriva alla sua soluzione con documenti MSDN e post sul blog di Scott Hanselman ecc.

Omar suggerisce di usare quanto segue

using (var db = new DropthingsDataContext2())
{
  db.Connection.Open();
  db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");

  var user = db.aspnet_Users.First();
  var pages = user.Pages.ToList();
}

mentre Javed Hasan suggerisce

using (new TransactionScope(TransactionScopeOption.Required, 
  new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
{
 //Your db Operation
}

Sono molto interessato a sapere cosa fate là fuori ragazzi su questo particolare problema su un sito ad alto volume come StatckOverflow, o cosa hanno fatto Jeff e i loro ragazzi al riguardo?

Modifica : dopo aver letto il primo post, voglio sottolineare alcune cose nel post di Omar.

  1. ha riscontrato un problema di connessione con il suo approccio ma lo ha risolto, vedi il suo post.
  2. ancora più importante, ha detto che ha provato a utilizzare la modalità Transazione ADO.NET e ha anche provato quello che Scott Hanselman ha scritto sul suo blog, ma non funziona per un sito di grandi volumi, ma degrada un po 'le prestazioni. Omar ha affermato che questo "System.Transactions ha un notevole sovraccarico. Non sono mai stato in grado di usarlo su un sito Web ad alto volume senza far andare la CPU al 100% e Req / sec scendere al 1/10. È progettato per applicazioni aziendali, non per siti Web di volume elevato. & Quot;
È stato utile?

Soluzione

Prima di tutto, evita letture non impegnate, possono causare molti problemi. Un approccio molto migliore consiste solo nell'impostare il database su isolamento snapshot . Questo è ciò che Jeff ha fatto .

Jeff ha sostanzialmente affermato: "bla bla bla, essere reali, bla bla bla, teorici del database, bla bla bla, LEGGI UNCOMMITTED possono essere utili per le app di REAL REAL che non necessitano di coerenza dei dati." Jeff non è un DBA, per fortuna ci sono molti DBA qui su SO.

Il problema con l'approccio di Omar è che può perdere connessioni con " leggi senza commit " livello di isolamento nel pool di connessioni che potrebbe causare danni nel tuo sito Web. Significa che un'istruzione casuale può essere eseguita in lettura senza commit.

L'approccio Javed sarebbe molto meglio perché in caso di SM gli MS hanno la possibilità di ripulire le cose dalla connessione.

MODIFICA Se stai riscontrando problemi di prestazioni con l'approccio di Javed, potresti guardare al lancio del tuo gestore delle transazioni.

Alcune cose che probabilmente vorresti fare:

  • Conserva una pila di transazioni correnti
  • Conferma di essere nel thread del creatore quando viene eseguita una transazione
  • Ripristina l'isolamento della transazione allo stato precedente al momento dell'eliminazione
  • Rollback su smaltimento se la transazione non è stata impegnata.
  • Supporta rollback nidificati.

Altri suggerimenti

Sono uno sviluppatore di un team di strumenti nel gruppo SQL Server di Microsoft. Molte applicazioni non sono estremamente sensibili alla coerenza delle transazioni, soprattutto se si scrive un'app che riporta o qualcosa in cui dati occasionalmente incoerenti non sono la fine del mondo. Naturalmente, se stai scrivendo un'applicazione finanziaria o qualcos'altro che ha una tolleranza molto bassa per l'incoerenza dei dati, probabilmente vorrai esplorare altre soluzioni.

Se scelgo di utilizzare letture senza commit, ho ha bloggato una soluzione pratica usando i metodi di estensione in C #.

{La mia (scarsa) reputazione mi impedisce di pubblicare commenti, quindi la metto come risposta}

Se si utilizza IsolationLevel tramite System.Transactions e si crea un nuovo contesto Linq all'interno del blocco delle transazioni, SQL Server finisce per provare a chiamare DTC per coordinare la transazione. Mi è appena successo ed è stato abbastanza inaspettato.

Per quanto riguarda le transazioni in .Net e l'effetto (in qualche modo sorprendente) del DTC, questo documento Presentazione di System.Transactions in .NET Framework 2.0 di Juval Lowy spiega le cose molto bene ed è ancora pienamente valido (.Net4). Vale la pena leggere. (Avrei anche pubblicato un commento ... se potessi.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top