2009-11-16 9 views
2

커밋되지 않은 변경 내용에 대한 쿼리를 수행해야하며 트랜잭션을 사용하려고했지만 예외가 있으면 트랜잭션이 작동하지 않는 것으로 나타났습니다.Entity Framework를 사용하여 트랜잭션을 롤백 할 수 없음

문제를 재현하기위한 간단한 예를 만들었습니다. "Tabella"라는 테이블이 하나 뿐인 데이터베이스가 있고 테이블에 두 개의 필드가 있습니다. "ID"는 자동 생성 된 정수이고 "Valore"는 고유 제한 조건이있는 정수입니다. 그럼이 코드를 실행하려고 :

using (TransactionScope scope = new TransactionScope()) 
{ 
    Db1Container db1 = new Db1Container(); 

    try 
    { 
     db1.AddToTabella(new Tabella() 
     { 
      Valore = 1 
     }); 
     db1.SaveChanges(); 
    } 
    catch { } 

    try 
    { 
     db1.AddToTabella(new Tabella() 
     { 
      Valore = 1 
     }); 
     db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown 
    } 
    catch { } 

    try 
    { 
     db1.AddToTabella(new Tabella() 
     { 
      Valore = 2 
     }); 
     db1.SaveChanges(); 
    } 
    catch { } 

    //scope.Complete(); //NEVER called 
} //here everything should be rolled back 

지금은 데이터베이스에 보면은 트랜잭션이 롤백해야하기 때문에, 대신에 나는 두 개의 레코드를 찾아 레코드가 포함되어야합니다 !!!! 1 개는 Valore = 1이고 다른 하나는 Valore = 2입니다. 내가 누락 된 항목이 있습니까? SaveChanges 메서드에 대한 두 번째 호출이 자체 변경 내용을 롤백하고 트랜잭션을 "삭제"하는 것처럼 보이면 SaveChanges에 대한 세 번째 호출은 첫 번째 및 세 번째 삽입의 변경 내용을 커밋합니다 (이 시점에서는 트랜잭션이 존재하지 않습니다).

또한 AcceptAllChanges 메서드를 호출하지 않고도 SaveChanges (false) 메서드를 사용하려고했지만 성공하지 못했습니다. 동일한 동작이 있습니다.

(예 : catch 문에서 사용자 상호 작용으로) 오류를 수정하고 다시 시도하기 때문에 SaveChanges에 의해 트랜잭션이 자동으로 롤백되는 것을 원하지 않습니다.

누군가가 도와 줄 수 있습니까? 그것은 "버그"처럼 보이고, 그것은 내게 정말로 큰 두통을주고 있습니다 ...

+0

어떤 DB가 사용되고 있습니까? – Lucero

+0

SQL Server 2008 – Luca

+0

이상한 동작 ... 코드에 대해 확신합니까? 대개 Db1Container도 닫히거나 폐기해야한다고 생각하십시오. –

답변

0

scope.Complete()은 절대로 불리지 않습니까? catch{} 모든 예외가 발생하면 코드가 계속 실행되고 완료 문에 도달합니다. 대신 예를 들어 예외를 전달하여 더 높은 수준에서 catch하도록해야합니다.

0

원래의 질문에는 다소 늦었지만 아마도 도움이 될 것입니다.

이 코드는 .net/ef 4 및 sql server 2008 R2와 함께 작동해야합니다.

using (TransactionScope scope = new TransactionScope()) 
{ 
    Db1Container db1 = new Db1Container(); 

    try 
    { 
     db1.AddToTabella(new Tabella() 
     { 
      Valore = 1 
     }); 
     db1.SaveChanges(); 

     db1.AddToTabella(new Tabella() 
     { 
      Valore = 1 
     }); 
     db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown 

     //if we get here then there were no errors thrown on previous SaveChanges() 
     //calls and we can complete the transaction with no rollback 
     scope.Complete(); 

    } 
    catch (Exception) 
    { 
     //do nothing 
    } 

} 
관련 문제