Development Tip

Linq to SQL을 사용한 NOLOCK

yourdevel 2020. 11. 4. 20:56
반응형

Linq to SQL을 사용한 NOLOCK


Linq2Sql이 SQL에서 NOLOCK을 방출하도록 할 수 있습니까? 그렇다면 어떻게?


예, 여기 내 블로그 의 항목이 있습니다 .

NOLOCK 힌트는 "격리 수준"이 "커밋되지 않은 읽기"로 설정된 트랜잭션에서 쿼리를 래핑하는 것과 본질적으로 동일합니다. 이는 쿼리가 읽고있는 행에 내용이 기록되는 과정에 있는지 상관하지 않음을 의미합니다. "더러운"데이터를 읽고 결과 집합의 일부로 반환합니다.

.NET 2.0에 도입 된 이전 System.Transactions 네임 스페이스를 사용하여 "커밋되지 않은 읽기"트랜잭션 전체를 수행 할 수 있습니다. 다음은 몇 가지 샘플 코드입니다.

using (var txn = new TransactionScope(
    TransactionScopeOption.Required, 
    new TransactionOptions
    {
        IsolationLevel = IsolationLevel.ReadUncommitted
    }
))
{
    // Your LINQ to SQL query goes here
}

그래서 새로운 TransactionScope 개체를 만들고 커밋되지 않은 읽기 격리 수준을 사용하도록 지시합니다. "using"문 내의 쿼리는 이제 모든 테이블이 NOLOCK 힌트로 읽는 것처럼 작동합니다.

다음은 "linq sql nolock"에 대한 Google 검색의 첫 번째 결과입니다.

InfoQ : LINQ to SQL 및 LINQ to Entities를 사용하여 NOLOCK 구현

Matt Hamilton-LINQ to SQL 및 NOLOCK 힌트 : Mad Props!

Scott Hanselman의 Computer Zen-LINQ to SQL 및 LINQ to ...


theKingMy ExtensionsLinqPad 추가 :

public static IQueryable<T> DumpNoLock<T>(this IQueryable<T> query)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.Dump();
    }   
}

public static System.Transactions.TransactionScope GetNewReadUncommittedScope()
{
    return new System.Transactions.TransactionScope(
        System.Transactions.TransactionScopeOption.RequiresNew,
        new System.Transactions.TransactionOptions
        {
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
        });
}
public static IQueryable<T> DumpNoLock<T>(this IQueryable<T> query, string description)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.Dump(description);
    }   
}

public static List<T> ToListNoLock<T>(this IQueryable<T> query)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.ToList();
    }   
}

public static U NoLock<T,U>(this IQueryable<T> query, Func<IQueryable<T>,U> expr)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return expr(query);
    }   
}

마지막 NOLOCKNoLock명시 적으로 작성 하지 않은 모든 평가 쿼리에 대해 수행 할 수 있음을 의미합니다 ( ToListNoLock위에서 설명한 것처럼). 예를 들면 다음과 같습니다.

somequery.NoLock((x)=>x.Count()).Dump();

로 쿼리를 평가합니다 NOLOCK.

Note that you have to ensure you're evaluating the query. E.g. .NoLock((x)=>x.Distinct()).Count().Dump() won't do anything usefully different from .Distinct().Count().Dump().


A simple way may be to run a command on your DataContext class

using (var dataContext = new DataContext())
{
  dataContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

  // Your SQL query
}

Here is an extension method to use with LINQPAD

    public static IQueryable<T> Dump2<T>(this IQueryable<T> query)
{
    using (var txn = new System.Transactions.TransactionScope(TransactionScopeOption.RequiresNew, 
        new TransactionOptions
        {       
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
        }))
    {
        return query.Dump();
    }   
}

Then you can call it as:

MyTable.Where(t => t.Title = "Blah").Dump2();

In my case, Entity Framework 5 (based on @Soppus answer):

private FoobarEntities db = new FoobarEntities();
public FoobarController()
{
    db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}

참고URL : https://stackoverflow.com/questions/1220807/nolock-with-linq-to-sql

반응형