同時実行性に問題があります。http://blogs.msdn.com/b/alexj/archive/2009/05/20/tip-19-how-to-use-optimistic-concurrency-in-the-entity-のオプティミスティック コンカレンシー処理を読みました。フレームワーク.aspx
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;
}
さらに、モデルの「コイン」同時実行モードを「固定」に設定しました。ただし、これはスルーされ、データベースに保存される値は「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 は 2 回目以降 1 回だけスローされます。2 番目の句はそれを既にある値に更新するため、その部分は論理的です。2 つのエンティティが同じコンテキストからフェッチされた場合、後者の変更は単純に考慮されるため、最初の応答で示唆されているように「1 つのデータベース接続」の場合、同時実行例外は発生しません。複数のハンドルを介してオブジェクトにアクセスしないようにすることはプログラマの責任であるため、これは論理的です。
私が得られないのは、DbUpdateConcurrencyException と OptimisticConcurrencyException の違いです。私は後者を上げることができませんでした。