私は教育の仕事をしており、私のコードで何が間違っているのか分かりません。私は、DBテーブルを更新し、トランザクションでこのロジックを分離しようとしています。最後に、私はデッドロックを取得します。私が間違っていることを誰かに説明することはできますか?
ここに私のスレッドの作成ロジック:EF:複数のスレッドで同じDBテーブルの行を更新します。
for (int i = 0; i < 10; i++)
{
var thread = new Thread(() => UpdateOrder(orderId));
threadList.Add(thread);
thread.Start();
}
foreach (var t in threadList)
{
t.Join();
}
//Display sum by order items amount and amount property from order entity
WriteAmount(orderId);
そしてUpdateOrder
方法
public static void UpdateOrder(int orderId)
{
using (var db = new OrderContext()
{
using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew
,new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
{
var o1 = new OrderItem { Title = "title", Amount = 50, Count = 1, OrderId = orderId };
db.OrderItems.Add(o1);
var order = db.Orders.Find(orderId); //Include(o => o.Items).Single(o => o.Id == orderId);
order.Amount += 50; //order.Items.Sum(oi => oi.Amount);
db.SaveChanges();
transactionScope.Complete();
}
}
}
私は、スレッドごとに独自のコンテキストを作成しました。私のDBがデッドロックを検出するのはなぜですか?
これは例外メッセージです:"トランザクション(プロセスID 51)が別のプロセスでロックリソースにデッドロックされ、デッドロックの対象として選択されました。トランザクションを再実行してください。
ありがとうございます!
おそらく、すべてのコンテキストとトランザクションでOrderItemsテーブルで書き込みロックが必要で、読み取り操作が完了するまでロックが解除されないためです。この結果、9つのコンテキストのデッドロックが発生します.2PLでは動作しません。また、DbContextはスレッドセーフではないことに注意してください。マルチスレッド環境で使用する場合、DbContextが完璧に動作することは期待できません。 – DevilSuichiro