2013-11-25 2 views
0

내 응용 프로그램에 EF 6 and Code First 데이터베이스 솔루션을 사용하고 있습니다. 동일한 응용 프로그램이 여러 컴퓨터에서 실행되고 동일한 데이터베이스에 액세스합니다. 데이터베이스의 한 정수 필드가 이러한 응용 프로그램에서 업데이트되면이 필드의 값이 감소됩니다. 아래 코드는 경쟁 조건 문제 일 수 있다고 생각합니다. 이 상황에서 어떻게 문제를 해결합니까?경쟁 조건을 방지하는 EF

public partial class CaContext 
{ 
    public override int SaveChanges() 
    { 
    var addedStatistics = ChangeTracker.Entries<Statistic>().Where(e => e.State == EntityState.Added).ToList().Select(p => p.Entity).ToList(); 

    var testOrders = GetUser.Orders.First(); 
    testOrders.Credits = testOrders.Credits - addedStatistics.Count; //Race condition here 


    return base.SaveChanges(); 
    } 
} 
+1

http://stackoverflow.com/questions을 : 당신은 여기에서 자세한 내용을 찾을 수

public void method() { using(var transactionScope = new TransactionScope()) { _context.SaveChanges(); } } 

: 그래서 그냥 트랜잭션 범위에() 호출 SaveChanges를을 마무리/6126616/is-dbcontext-thread-safe), 경쟁 조건이 가장 적은 문제입니다. –

+0

더 자세히 설명해주세요! – Tomas

답변

2

하나의 옵션은 읽기, 계산, 쓰기를 수행하는 대신 값을 감소시키는 업데이트 명령문을 수행하는 것입니다.

Database.SqlCommand(
    @"UPDATE [CreditCount] 
    SET [Credits] = [Credits] - x 
    WHERE [UserID] = y" 
); 
0
  1. 나는 전체적인 디자인을보고 같은 카운터를 제거합니다. 예를 들어 변경 사항을 저장할 때마다 새 레코드를 추가 할 테이블을 만들 수 있습니다. 거기서 카운트를 설정 한 다음 SUM 쿼리를 사용하여 총계를 얻습니다. 이렇게하면 문제가 해결됩니다.

  2. 저장 프로 시저를 만들고 호출 할 수있는 것보다 하나의 필드가 실제로 필요한 경우. SP는 데이터베이스에서 실행되며 데이터에 대한 액세스가 동기화됩니다.

0

트랜잭션 범위 내에서 작업을 수행하십시오. 올바른 격리 수준을 설정해야 할 수도 있습니다. 앞에`DbContext` [하지 스레드 (http://msdn.microsoft.com/en-us/data/dn456843#transactionScope

+0

격리 수준은 이와 같이 작동하지 않습니다. 그는 현재 값을 읽을 때 HOLDLOCK과 같은 테이블 뒷다리를 추가해야합니다. 이것이 EF를 통해 가능한지 확실합니다. –

관련 문제