2014-07-21 2 views
0

저는 TransactionScope와 함께 Entity Framework를 사용하고 있습니다. TransactionScope의 Complete() 메서드를 한 번 호출하면 교착 상태 문제가 발생하면 모든 변경 사항이 롤백되지 않는 문제가있는 것 같습니다. 이 TransactionScope 내에서 두 개의 개별 데이터베이스를 업데이트 중이므로 교착 상태 문제가 발생한 데이터베이스의 변경 내용 만 롤백한다는 점에 유의하십시오.Entity Framework TransactionScope 롤백 문제

코드 예 : 외부 ID가를 삽입 할 때 우리가 얻을 신원 기록이기 때문에 위의 예에서

try 
{ 
    using (TransactionScope scope = new TransactionScope()) 
    { 
     //Insert into database1 (getting the deadlock issue) 
     database1.SaveChanges(); 
     //Update ExternalId (Identity PK from database1) in database2 
     database2.SaveChanges(); 
     scope.Complete(); 
    } 
} 
catch (Exception ex) 
{ 
    throw; 
} 

는 DATABASE2는 업데이트 이전 외부 열을 얻을 수 있지만 기록은 이상한 database1에 삽입되지 않습니다 database1에 기록하십시오.

+0

TransactionScope를 만든 후에 database1과 database2를 만들고 있습니까? –

+0

아니요, 클래스 변수입니다. 그것이 문제일까요? – donpmill

+1

수도 있습니다. DbContext는 처음 데이터베이스에 연결될 때 TransactionScope에 참가합니다. Linq를 실행하고, SaveChanges를 호출하고, CommandTimeout과 같은 몇 가지 연결 옵션을 설정하는 것은 데이터베이스 연결을 여는 몇 가지 방법입니다. 사람들이 대개 SqlConnection을 클래스 수준 필드/속성으로 만들지 않는 것과 유사하게 즉시 열고 닫으므로 클래스 변수로 dbcontext를 만드는 것을 권장하지 않습니다. 따라서 TransactionScope 용 블록을 사용하는 것과 마찬가지로 dbContextes를 아래에 만들고 using 블록에 배치해야합니다. –

답변

0

연결이 TransactionScope 외부에서 만들어지고 열리면 Connection.EnlistTransaction(Transaction.Current);을 호출하여 트랜잭션에 수동으로 참여시켜야합니다. 예 :

try 
{ 
    using (TransactionScope scope = new TransactionScope()) 
    { 
     database1.Connection.EnlistTransaction(Transaction.Current); 
     database2.Connection.EnlistTransaction(Transaction.Current); 

     //Insert into database1 (getting the deadlock issue) 
     database1.SaveChanges(); 
     //Update ExternalId (Identity PK from database1) in database2 
     database2.SaveChanges(); 
     scope.Complete(); 
    } 
} 
catch (Exception ex) 
{ 
    throw; 
}