2

У меня проблема с некоторыми параллелизмами. Я прочитал в Оптимистический параллелизме Обращение в http://blogs.msdn.com/b/alexj/archive/2009/05/20/tip-19-how-to-use-optimistic-concurrency-in-the-entity-framework.aspxПараллелизм с Entity Framework & SQL (ADO.NET)

У меня есть кусок кода, чтобы проверить это на практике в моей службе WCF:

public GameResult PurchaseGameItem(int itemId) 
    { 
     using (var entities = new GameEntities()) 
     { 
      var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault(); 
      p1.Coins = 1; 

      using (var e2 = new GameEntities()) 
      { 
       var p2 = e2.Items.Where(p => p.ID == itemId).FirstOrDefault(); 
       p2.Coins = 2; 
       e2.SaveChanges(); 
      } 

      entities.SaveChanges(); 
     } 

     return GameResult.Success; 
    } 

Кроме того, я устанавливал «Монету» Concurrency Mode в модели на «Исправлено». Однако это продолжается, и значение, сохраненное в базе данных, равно «1». Я пробовал с несколькими наборами значений, так что это не так, что это «правильно случайно». Почему здесь не возникает исключение OptimisticConcurrencyException?

[обновление # 1] пробуя первый ответ ниже и комбинируя их, мне удалось получить DbUpdateConcurrencyException из иногда. Это все еще не исключение OptimisticConcurrencyException, которое я ожидаю, но это что-то. В принципе, я понятия не имею, почему это не происходит все время.

  var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault(); 
      var p3 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault(); 

      p1.CoinValue = 14; 
      p3.CoinValue = 115; 

      using (var e2 = new GameEntities()) 
      { 
       var p2 = e2.Items.Where(p => p.ID == itemId).FirstOrDefault(); 
       p2.CoinValue = 72; 
       e2.SaveChanges(); 
      } 

      entities.SaveChanges(); // This throws DbUpdateConcurrencyException, perhaps 50% of the time. 

Похоже, проблема параллелизма здесь! : D

[обновление # 2] Хорошо, я решил часть его сейчас, и это была в основном глупая ошибка пользователя. DbUpdateConcurrencyException выбрасывается только один раз со второго раза, второе предложение будет обновлять его до значения, в котором оно уже находится, поэтому эта часть логична. Если два объекта были выбраны из одного и того же контекста, последнее изменение будет просто учтено, поэтому в случае «одного подключения к базе данных», как было предложено первым ответом, исключение параллелизма не возникает. Это логично, так как программисту не нужно обращаться к объекту с помощью нескольких ручек.

То, что я не понимаю, есть разница между DbUpdateConcurrencyException и OptimisticConcurrencyException. Я не могу поднять последнее.

ответ

2

OptimisticConcurrencyException - это ADO.NET, который лежит в основе ADO.NET Entity Framework. Исключение DbUpdateConcurrencyException генерируется Entity Framework. Вы не должны сталкиваться с исключением OptimisticConcurrencyException при использовании Entity Framework без использования прямого ADO.NET через объект connection/command.

0

Я удивляюсь, почему вы создали 2 подключения к базе данных ?!

public GameResult PurchaseGameItem(int itemId) 
{ 
    using (var entities = new GameEntities()) 
    { 
     var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault(); 
     var p2 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault(); 

     p1.Coins = 1; 
     p2.Coins = 2; 

     entities.SaveChanges(); 
    } 

    return GameResult.Success; 
} 
+0

Моя логика заключалась в том, чтобы просто имитировать более реалистичный сценарий проблемы параллелизма. Он не предназначен как какой-либо фактический, функциональный код. При этом ваш подход дает тот же результат. Нет ошибки. – Muhwu

+0

О, как я упоминал в своем обновлении, это не вызывает никаких ошибок. Вы просто получаете две ссылки на один и тот же объект и в том же контексте, это не проблема (если я не понял, как все работает). – Muhwu

+0

Да, вам нужно два соединения с DBContext, которые меняют одну и ту же базу данных записей в одно и то же время, чем вы получите ConcurrencyException. –

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