Entity Framework를 사용하면 대부분 SaveChanges()
충분합니다. 그러면 트랜잭션이 생성되거나 주변 트랜잭션에 참여하고 해당 트랜잭션에 필요한 모든 작업이 수행됩니다.
때로는 SaveChanges(false) + AcceptAllChanges()
페어링이 유용 하지만 .
가장 유용한 장소는 두 개의 다른 컨텍스트에서 분산 트랜잭션을 수행하려는 경우입니다.
즉 다음과 같은 것 (나쁜) :
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save and discard changes
context1.SaveChanges();
//Save and discard changes
context2.SaveChanges();
//if we get here things are looking good.
scope.Complete();
}
경우 context1.SaveChanges()
성공하지만 context2.SaveChanges()
전체 분산 트랜잭션이 중단됩니다 실패합니다. 그러나 불행히도 Entity Framework는의 변경 사항을 이미 삭제 context1
했기 때문에 실패를 재생하거나 효과적으로 기록 할 수 없습니다.
그러나 코드를 다음과 같이 변경하면
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save Changes but don't discard yet
context1.SaveChanges(false);
//Save Changes but don't discard yet
context2.SaveChanges(false);
//if we get here things are looking good.
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();
}
호출 SaveChanges(false)
이 필요한 명령을 데이터베이스 에 전송하는 동안 컨텍스트 자체는 변경되지 않으므로 필요한 경우 다시 수행하거나 ObjectStateManager
원하는 경우 질문 할 수 있습니다 .
즉, 트랜잭션이 실제로 예외를 발생시키는 경우 각 컨텍스트의 상태를 다시 시도하거나 로깅하여 ObjectStateManager
어딘가에 보상 할 수 있습니다 .
자세한 내용은 내 블로그 게시물 을 참조하십시오 .
SaveChanges(fase); ... AcceptAllChanges();
패턴이 처음 인지 이해하는 데 도움 이 되었습니다 . 위의 질문에 대한 대답이 블로그 작성자에 의해 어떻게 작성되었으며 그 질문이 다른 질문에서 참조 되는지 확인하십시오 . 모두 함께 제공됩니다.