EF:在多个线程

时间:2017-06-23 05:53:35

标签: c# multithreading entity-framework

我有一项教育任务,不明白我的代码中有什么问题。我正在尝试更新数据库表并在事务中隔离此逻辑。最后,我遇到了僵局。有人可以向我解释一下我做错了什么吗? 这是我的线程创建逻辑:

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();
        }
    }
}

我为每个线程创建了自己的上下文。为什么我的数据库检测到死锁? 这是异常消息:“事务(进程ID 51)在锁资源上与另一个进程死锁,并被选为死锁牺牲品。重新运行该事务。”
提前谢谢!

1 个答案:

答案 0 :(得分:1)

您在数据库方面遇到问题。 为什么使用READ COMMITTED交易类型?假设这是原因。 您可以在此处阅读有关不同隔离级别的信息:https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql

我会建议你:  1.将隔离级别更改为默认order.Amount += 50;  2.删除 <p ng-bind="f1" ></p> <p ng-bind="f2" ></p> <p ng-bind="f3" ></p> <button ng-click="write("f1")" >Save</button> 。而是在数据库端创建一个触发器来处理OrderItems表上的INSERT / UPDATE / DELETE事件并修改Orders表。