Domanda

Sto cercando di ottenere una maniglia su se abbiamo un problema nella nostra applicazione con connessioni al database utilizzando IsolationLevels non corretti. La nostra applicazione è un App NET 3.5 database utilizzando SQL Server 2005.

ho scoperto che l'IsolationLevel di connessioni non vengono reimpostati quando sono restituiti al pool di connessioni (vedi qui ) ed era anche molto sorpreso di leggere in questo post sul blog che ogni nuova TransactionScope creato ottiene il proprio pool di connessioni ad essa assegnati.

I nostri aggiornamenti del database (attraverso i nostri oggetti di business) si svolgono all'interno di un TransactionScope (uno nuovo viene creato per ogni aggiornamento grafico oggetto di business). Ma i nostri recuperi non usano una transazione esplicita. Quindi quello che mi chiedo è potremmo mai entrare in una situazione in cui la nostra recuperare operazioni (che dovrebbe utilizzare l'IsolationLevel default - Read Committed) sarebbe riutilizzare una connessione dal pool che è stato usato per un aggiornamento, e ereditare l'IsolationLevel aggiornamento (RepeatableRead)? O sarebbero i nostri aggiornamenti garantiti per utilizzare un pool di connessione diverso visto che sono avvolti in un TransactionScope?

Grazie in anticipo,

Graham

È stato utile?

Soluzione

che preoccupa!

L'articolo di Bill Vaughan si è collegato a stati che '... ogni TransactionScope ottiene la propria piscina', ma il codice nel articolo di supporto si è collegato al, suggerisce che non è vero, dal momento che secondo run del NoTxScope() ottiene la connessione da la piscina che ha usato il livello di isolamento elevata.

Si puo 'forza' il problema [sto disegnando sul codice dal primo link]:

static void ForceReadCommitedScope()
{
    TransactionOptions op = new TransactionOptions();
    op.IsolationLevel = IsolationLevel.ReadCommitted;
    using (TransactionScope tx = new TransactionScope(TransactionScopeOption.RequiresNew, op))
    {
        SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=master;Integrated Security=True;");
        SqlCommand com = new SqlCommand("select transaction_isolation_level from sys.dm_exec_sessions where (session_id = @@SPID)", con);
        con.Open();
        short level = (short)com.ExecuteScalar();
        Console.WriteLine("transaction_isolation_level : " + level.ToString());
        con.Close();
        tx.Complete();
    }
}

o aggiungendo "..;Pooling=False" per la stringa di connessione.

Altri suggerimenti

Nel SQL Server 2014 il livello di isolamento per la connessione in pool viene resettato quando la connessione viene restituita al pool. Nelle versioni precedenti non lo è.

Vedi questo post sul forum:

  

" in SQL 2014, per i driver client con la versione TDS 7.3 o superiore, SQL server sarà ripristinare il livello di isolamento delle transazioni di default (leggi impegnati) per le connessioni in pool. per i clienti con la versione TDS inferiori 7.3 avranno il vecchio comportamento durante l'esecuzione contro SQL 2014. "

Aggiornamento

Questo nuovo cambiato di nuovo al comportamento precedente in SQL 2014 CU6 e SQL 2014 SP1 CU1 con questa correzione:

FIX: il livello di isolamento delle transazioni viene ripristinato in modo non corretto quando la connessione SQL Server viene rilasciato in SQL Server 2014

  

"Si supponga che si utilizza la classe TransactionScope nel codice sorgente sul lato client SQL Server, e non si apre in modo esplicito la connessione SQL Server in una transazione. Quando la connessione SQL Server viene rilasciato, il livello di isolamento delle transazioni viene ripristinato in modo non corretto. "

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