4

TransactionScopeを使用して、ReadUncommittedに分離レベルを設定して、特定のクエリを実行するオプションを使用してテストしています。ただし、接続で分離レベルが設定されているため、接続が他のクエリで再利用されると、分離レベルは既定のReadCommittedにリセットされるのではなく、ReadUncommittedです。NOLOCKのLINQからSQLへのTransactionScopeを使用した分離レベルの変更は接続に影響しますか?

public static class QueryableExtensions 
{ 
    static TransactionScope CreateNoLockTransaction() 
    { 
     return new TransactionScope(TransactionScopeOption.Required, new TransactionOptions 
     { 
      IsolationLevel = IsolationLevel.ReadUncommitted 
     }); 
    } 

    public static T[] ToNoLockArray<T>(this IEnumerable<T> query) 
    { 
     using (var ts = CreateNoLockTransaction()) 
     { 
      return query.ToArray(); 
     } 
    } 

    public static List<T> ToNoLockList<T>(this IEnumerable<T> query) 
    { 
     using (var ts = CreateNoLockTransaction()) 
     { 
      return query.ToList(); 
     } 
    } 

    public static int NoLockCount<T>(this IEnumerable<T> query) 
    { 
     using (var ts = CreateNoLockTransaction()) 
     { 
      return query.Count(); 
     } 
    } 
} 

が、私はその後、私はトランザクションのスコープ内となしの両方を実行して、様々なクエリの分離レベルを確認したい:次のように多くの示唆パー

は、私は拡張機能として新しいNOLOCK方法を抽象化。 NOLOCKの拡張メソッドを実行する前に上記を実行

db.ExecuteQuery<int>("select cast(transaction_isolation_level as int) from sys.dm_exec_sessions where session_id = @@SPID").FirstOrDefault(); 

NOLOCKの拡張メソッドを実行し、分離レベルをチェックした後2として分離レベルを返します。私は、クエリのコンテキストを使用して、次のクエリを実行し始めたことを行うために、

これは、影響を受けた接続がTransactionScopeを使用して分離レベルを変更すると、他のクエリおよびデータコンテキストで再利用されると、ReadUncommitted分離レベルを引き続き使用することを意味しますか?特定のクエリの分離レベルを一時的に変更するためにトランザクションを使用する目的は、それ以降のすべてのクエリに影響するため、その目的を無効にしませんか?

+0

トピックオフ - 私はあなたが 'READ UNCOMMITTED'がダーティリードを返すことができると確信しています。これには、技術的にはデータベースの一部ではないレコードも含まれます。 [ソース - MSDN](https://msdn.microsoft.com/en-GB/library/ms173763.aspx)詳細については、[このブログのエントリ](http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/)を参照してください。 –

+0

そうですね、私は、READ COMMUNITEDの分離レベルを使ってダーティーリードを考慮しても問題ないと思う特定のクエリだけを実行したいのです。問題はLINQ to SQLでそれを実現するソリューションであり、おそらくEFでも他のクエリにも影響を与えています。これは望ましい動作ではありません。 –

+0

これは、[4分7分40秒](http://www2.sys-con.com/itsg/virtualcd/dotnet/archives/0112/smith)の間にある接続プールの実際の接続に関連している必要があります/index.html)。 –

答えて

0

クエリ後

ts.Complete() 

を使用してスコープを閉じる必要があり、戻り

0

前に、私たちは、このように正確に同じ問題を抱えています。 LINQ to SQLを使用し、TransactionScopeオブジェクトを使用すると、sql spid全体がコミットされずに読み取られます。

これは私が唯一の現在のクエリがコミットされていないお読みくださいに見つけることができる唯一の方法である:

dbContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"); 

var Data = query.ToList(); 

dbContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ COMMITTED"); 

をSQLプロセスで実行中の他のクエリがで影響を受ける可能性があるので、これは明らかにそれを行うための素晴らしい方法ではありません数ミリ秒の間オープンされ、DBサービスへの2つの追加コールが生成されます。

LINQがselect文の中でトランザクション分離レベルを生成する方法がある場合は、より良いものになります。

関連する問題