2013-02-19 15 views
6

Quando si salvano i dati nel database ho utilizzato TransactionScope con IsolationLevel impostato su Serializable.Modifica TransactionScope IsolationLevel dopo aver completato la transazione

TransactionOptions options = new TransactionOptions 
     { 
      IsolationLevel=IsolationLevel.Serializable 
     }; 


using (var transaction = new TransactionScope(TransactionScopeOption.Required,options)) 
{ 
    transation.Complete(); 
} 

Ora dopo che l'esecuzione è finita, voglio cambiare TransactionScopeIsolationLevel.

Modifica

Quello che ho capito è questo, se IsolationLevel impostato a Serializable poi, dopo il completamento della transazione, l'oggetto di connessione è chiusa e ritornare al pool di connessione e quando qualche altra richiesta arriva si recuperare quell'oggetto connessione da il pool e quindi effettuato dal precedente IsolationLevel. Quindi voglio cambiare il livello di isolamento al valore predefinito dopo ogni transazione.

risposta

5

Hai ragione: il livello di isolamento non viene ripristinato quando si restituisce una connessione al pool. Questo è un comportamento orribile, ma siamo bloccati con esso ...

Ci sono due strategie:

  1. ripristinare il livello di isolamento prima di tornare: Questo è il tuo approccio.
  2. Utilizzare sempre una connessione con una transazione esplicita (o TransactionScope) in modo che il livello di isolamento sia garantito.

Vi consiglio di fare quest'ultimo.

Se si insiste a fare (1) è possibile semplicemente modificare il livello di isolamento dopo aver chiuso il TransactionScope ma si deve fare questo con l'oggetto di connessione. Esempio:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    using (var transaction = new TransactionScope(TransactionScopeOption.Required,options)) 
    { 
     connection.Open(); //open inside of scope so that the conn enlists itself 
     transation.Complete(); 
    } 
    //conn is still open but without transaction 
    conn.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL XXX"); //pseudo-code 
} //return to pool 

Questo funziona per voi?

+0

Grazie per la risposta, sono pronto ad accettare altre opzioni migliori, ma come si suggerisce di aprire tutte le connessioni con transazioni esplicite, non pensate che questo porterà un sacco di spese generali nel sistema. Ho un'applicazione enorme centinaia di endpoint ma ci sono solo un paio di scenari in cui sto usando TransactionScope. Cosa suggerisci per queste cose? – MegaMind

+0

Il sovraccarico della transazione è quasi nulla, poiché tutte le dichiarazioni utilizzano comunque una transazione implicita .; Se non riesci a migrare tutto il tuo approccio potrebbe effettivamente essere una buona idea. Un trucco, ma una soluzione pragmatica. Non riesco a vedere grandi problemi con esso. – usr

+0

conn.ExecuteCommand ("SET TRANSACTION ISOLATION LEVEL XXX"); lavoro? Qualcuno l'ha provato? – hazimdikenli

2

Sono stato un po 'da questo. Fortunatamente la logica della stringa di connessione era centralizzata. Quello che ho fatto è stato modificare l'impostazione dell'applicazione della stringa di connessione se Transaction.Current non è null (il che implicherebbe che siamo all'interno di TransactionScope).

In questo modo le connessioni TransactionScope non si raggruppano con le altre.

Problemi correlati