2013-03-27 3 views
0

Я пытаюсь обновить поле своего объекта и сохранить его сразу в базе данных.Неожиданное исключение оптимистической параллелизма

using (var ctx = new DataModel(_connectionString)) 
{ 
    var MyObject it = ctx.MyObjects.Where(someConstraint).ToList()[0]; 
    try 
    { 
     //update check time 
     ctx.Refresh(RefreshMode.StoreWins, it); //making sure I have it 
     ctx.AcceptAllChanges(); // in case something else modified it - seems unnecessary 
     it.TimeProperty= DateTime.UtcNow; //Setting the field 
     ctx.DetectChanges(); //seems unnecessary 
     ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); //no SaveOptions changed the behavior 
    } 
    catch (OptimisticConcurrencyException) 
    { 
     _logger.DebugFormat(workerClassName + ": another worker just updated the LastCheckTime"); 
    } 
    //Do some other work and/or sleep 
} 

Когда я запускаю это в Azure эмулятор с 2 экземплярами или больше, я получаю много OptimisticConcurrencyExceptions здесь.

Я пытаюсь обновить объект, обновить одно из его полей, а затем переместить эти изменения в базу данных. Однако Оптимистический параллелизм мешает мне.

примечание: оптимистический параллелизм установлен на поле TimeStamp, которое я никогда не касаюсь.

Почему это и как его исправить?

ответ

1

Возможно, у вас есть несколько потоков внутри этого блока try, изменяя их собственные копии одного и того же объекта после того, как оба обновились от БД, но до того, как они сохранили свои изменения.

Попробуйте это:

using (var ctx = new DataModel(_connectionString)) 
{ 
    bool saved = false; 

    do 
    { 
     var MyObject it = ctx.MyObjects.Where(someConstraint).ToList()[0]; 

     try 
     { 
      it.TimeProperty= DateTime.UtcNow; //Setting the field 
      ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); 

      saved = true; 
     } 
     catch (OptimisticConcurrencyException) 
     { 
      _logger.DebugFormat(workerClassName + ": another worker just updated the LastCheckTime"); 

      ctx.Refresh(RefreshMode.StoreWins, it); 
      ctx.AcceptAllChanges(); 
     } 
    } while(!saved) 
    //Do some other work and/or sleep 
} 

Если это работает для вас, изменить условие время, чтобы ограничить количество попыток.

+0

no - У меня есть несколько процессов, выполняющих один и тот же код, но каждый процесс является однопоточным. – iliaden

+0

Возможно, отдельные процессы одновременно изменяют один и тот же объект. Обращайтесь к обновлению после возникновения исключения – Moho

+0

Меня не волнует обновление - мне нужно нажать это в БД. Локально переменная 'it' никогда не используется после этого. Также - я только что проверил с помощью отладчика: этот код работает в одном потоке на каждом из процессов – iliaden

Смежные вопросы