2012-01-31 3 views
1

EF 코드로 생성 된 데이터베이스가 있습니다. 데이터 조작은 DbContext을 사용하여 수행됩니다. Asp.net 응용 프로그램의 IoC 컨테이너는 DbContext 인스턴스를 생성하며 BL 개체는 스레드 단위로 의존합니다. 는 웹 응용 프로그램과 함께로드되는 백그라운드 작업 클래스입니다.다른 스레드에서 변경 사항을 저장할 때 EF concurency 추적

매 10 분마다 하나씩, 백그라운드 스레드는 트랜잭션 범위 내에서 myDbContext.Add을 호출하여 Incidents 목록에 하나의 항목을 추가합니다. Incidents 중 하나가 "웹 요청 스레드"에 myDbContext에 의해 변경되는 경우, 변경 사항이 잠시 데이터베이스에 저장됩니다에도 불구하고, 그들이 Incidents의 설정에 의해 무시지고처럼

한편, 그것은 보인다 사용자가 웹 페이지를 사용하여 Incident을 바꾸기 몇 초 전에 백 그운드 스레드에 의해 잡아 당겨졌다.

이것은 동시성 문제처럼 보입니다 (그리고 Timestamp 열과 같은 concurency를 구현하지 않습니다).

내 질문은 : 배경 스레드는 변경된 데이터 만 저장하면 안됩니다 (제 경우에는 새 인시던트 추가). 전체 인시던트 컬렉션을 남겨 두어야합니까? 참으로 사실이라면, 내 문제는 다른 곳에서 발생합니다. 백그라운드 스레드에서

코드 : 서브 루틴 RegisterRecurringTicket(scheduledTask);에서

using (var transaction = new TransactionScope()) 
      { 
       foreach (var scheduledTask in _db.ScheduledTasks) 
       { 
        if (scheduledTask.NextExecuteAfterDate == null) 
        { 
         PopulateNextExecuteAfterDate(scheduledTask); 
         shouldSaveChanges = true; 
        } 

        if (DateTime.Now > scheduledTask.NextExecuteAfterDate) 
        { 
         RegisterRecurringTicket(scheduledTask); 
         CalculateNextTime(scheduledTask); 
         shouldSaveChanges = true; 
        } 
       } 

       if (shouldSaveChanges) _db.SaveChanges(); 
       transaction.Complete(); 
      } 

코드는 사건 컬렉션에 항목을 추가합니다. _db.SaveChanges();이 호출되면 이전 버전의 인시던트로 인시던트 컬렉션을 덮어 쓰고 UI에서 생성 된 변경 사항을 인시던트 컬렉션으로 캐스팅 한 것처럼 보입니다. 그렇다면이 문제를 어떻게 해결할 수 있습니까?

답변

0

문제는 내가 PerThreadScopeDbContext 주사를 사용하고 있다는 것이 었습니다. 이로 인해 내 ASP.NET 응용 프로그램의 예기치 않은 동작이 발생했습니다. Ninject 모듈을 DbContext에서 PerRequestScope로 설정하면 문제가 해결되었습니다.

0

단순히 myDbContext.Incidents.ToList()을 호출해도 데이터베이스에 어떤 것도 덮어 쓰지 않습니다. 당신이 두 클래스가 같은 맥락을 가지고 있기 때문에 Incident의 직접 myDbContext에서가, 그들에 주입 당겨하지 않을에도 불구하고, 위의 예에서

// My Incident tracker 
IEnumerable<Incident> CurrentIncidents {get{return myDbContext.Incidents.ToList();}} 

// Meanwhile, in another class on the same thread... 
foreach(var incident in IncidentTracker.CurrentIncidents) 
{ 
    var claims = myDbContext.Claims.Where(c => c.IncidentId == incident.IncidentId); 
    foreach(var claim in claims) 
    { 
     Process(claim); 
    } 
    incident.Processed = true; 
} 
myDbContext.SaveChanges(); 

그러나, 나는 쉽게이 같은 상황을 상상할 수 SaveChanges()으로 전화하면 실제로 변경하려는 소유권과 변경하지 않은 인시던트에 모두 영향을줍니다.

이런 일이 일어날 가능성이 있습니까?

+0

예. 나는 문제의 셋업에 대해 질문 독자들에게 잘못된 정보를 제공한다는 것을 발견했다. 이것을 봐주세요. –

관련 문제