У меня проблема с некоторыми параллелизмами. Я прочитал в Оптимистический параллелизме Обращение в 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. Я не могу поднять последнее.
Моя логика заключалась в том, чтобы просто имитировать более реалистичный сценарий проблемы параллелизма. Он не предназначен как какой-либо фактический, функциональный код. При этом ваш подход дает тот же результат. Нет ошибки. – Muhwu
О, как я упоминал в своем обновлении, это не вызывает никаких ошибок. Вы просто получаете две ссылки на один и тот же объект и в том же контексте, это не проблема (если я не понял, как все работает). – Muhwu
Да, вам нужно два соединения с DBContext, которые меняют одну и ту же базу данных записей в одно и то же время, чем вы получите ConcurrencyException. –