2012-12-07 2 views
1

저는 지난 몇 시간 동안 인터넷 검색을 해왔지만 답변을 찾지 못했기 때문에 여기 누군가가 올바른 방향으로 나를 안내 할 수 있기를 바랍니다.TransactionScope, EF DbContext 및 Dirty Read

TransactionScope 내에서 EF DbContext (코드 우선)로 더티 읽기를 수행하는 방법을 알고 싶습니다.

using(TransactionScope scope2 = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions{IsolationLEvel = IsolationLevel.ReadUncommitted})) 
{ 
    var objects = context.SomeTable.Where(...).Select(...); //times out here on the 
} 

적절한 방법은 무엇입니까 : 예

DbContext context = new MyEntities(); 
using(TransactionScope scope = new TransactionScope()) 
{ 
    context.SomeTable.Add(someObject); 
    context.SaveChanges(); 

    var objects = context.SomeTable.Where(...).Select(...); //times out here on the read, because the write above locks the tables 
    //modify each object 
    context.SaveChanges(); 

    scope.Complete(); //transaction is a success only if the entire batch succeeds 
} 

위해 나는 다음과 읽기 호출을 래핑 시도?

+0

무슨 RDMS를 사용합니까? 일반적으로 작성자는 SQLServer가 아니면 독자를 차단해서는 안됩니다. 그러나 SQLServer의 경우에도 더티 읽기를 사용하는 것보다 나은 해결책이 있습니다. 데이터베이스에 대해 READ_COMMITTED_SNAPSHOT을 활성화 할 수 있습니다. – a1ex07

+0

삽입 된 개체의 ID를 잡는 것처럼 보입니다. 삽입 한 후에 개체를 선택하는 것보다 쉬운 방법이 있습니다. 이 경우인가요? – SmartK8

+0

"읽기 시간이 여기에 있습니다. 왜냐하면 위의 쓰기가 테이블을 잠급니다. 왜냐하면 읽기가 동일한 트랜잭션에서 발생하기 때문입니다. 트란이 왜 스스로를 막을까요? 또한, 쓰기는 전체 테이블 (신화)을 잠그지 않습니다. – usr

답변

0

서버에서 alter database your_db_name set READ_COMMITTED_SNAPSHOT on; (SQLServer 2005에서 사용 가능)을 실행할 수 있으며 판독기는 쓰기 작업자에 의해 차단되지 않습니다 (트랜잭션 읽기 수준은 read committed 격리 수준 임).

+0

아, 그래,이게 가장 논리적으로 들리네 ... 현재 해제되어 있습니다. DBA에게이 사실을 변경하도록 요청할 것입니다 ... – Alfred

1

마지막으로 문제가 무엇인지를 클릭했습니다. EF는 TransactionScope L2S와 잘 통합되어 있지 않습니다. 이것은 EF가 서버를 필요로하는 각 작업 (변경 사항 저장 또는 쿼리 저장)에 대한 연결을 열고 닫음을 의미합니다.

이렇게하면 분산 트랜잭션과 분산 교착 상태가 발생합니다.

이 문제를 해결하려면 EF StoreConnection을 수동으로 열고 닫아서 트랜잭션 기간 동안 정확히 하나의 연결이 있는지 확인하십시오.

1

당신은이 같은 TransactionScope에의 IsolationLevel을 설정할 수 있습니다 ...

var transactionOptions = new System.Transactions.TransactionOptions(); 
transactionOptions.Timeout = new TimeSpan(0, 0, 30); 
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted; 
using (var transactionScope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, transactionOptions)) 
{ 
... 
}