【发布时间】:2015-07-20 10:51:00
【问题描述】:
我要...
Transaction (Process ID xx) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
...在下面的代码中。怎么会?
// SIMPLE ORDERNUMBER LOGIC
var orderNumber = 1;
Order order = null;
using (TransactionScope scope = new TransactionScope())
{
if (db.Orders.Any(o => o.OrderNumber.HasValue))
{
// 1. Get the last successful order OrderNumber
var lastSuccessfulOrder = db.Orders.Where(o => o.OrderNumber.HasValue).OrderByDescending(o => o.OrderNumber).FirstOrDefault();
if (lastSuccessfulOrder != null)
{
orderNumber = lastSuccessfulOrder.OrderNumber.Value + 1;
}
}
// 2. Create the new order with null values except OrderNumber column
order = new Order();
order.OrderNumber = orderNumber;
db.Orders.Add(order);
System.Threading.Thread.Sleep(2000);
db.SaveChanges();
scope.Complete();
}
我正在 SQL Profiler 中查看死锁图,但说实话我无法真正理解。
Thread.Sleep(2000) 我放在那里是为了模拟一个需要更长处理时间的事务;顺便说一句,这在某种程度上似乎是罪魁祸首,因为当我删除它时,我没有遇到任何僵局。有什么想法吗?
以下是死锁图:
【问题讨论】:
-
您是否仅将
Thread.Sleep()用于测试目的?用它来模拟长时间运行的事务似乎很奇怪。 -
您使用的是哪个隔离级别?如果您正在使用 Serializable 尝试更改为 Read Commited (如果它有效,请考虑这是否会影响您)如果您发布死锁图,那会很好
-
@Kamo 是的。我想不出其他选择。对此有什么建议吗?在交易中以这种方式使用它对我来说似乎也很奇怪。嗯。
-
@Juan 默认。哪个是可序列化的。
-
@PussInBoots - 如果你真的想模拟后台任务运行(我相信它是为了 UI/UX 目的)你可以使用简单的
setTimeout()使用 JavaScript(如果你正在构建 Web 应用程序)。
标签: c# sql entity-framework entity-framework-6 transactionscope