我得到了......
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事件探查器,但实际上我无法理解它。
Thread.Sleep(2000)
我在那里模拟了一个需要花费更长时间来处理的事务;哪个btw似乎是某种方式的罪魁祸首,因为当我删除它时,我没有遇到任何僵局。有什么想法吗?
以下是死锁图:
答案 0 :(得分:1)
因此,由于Serializable隔离级别,死锁图看起来像是死锁。想想这个场景:
您可以通过不同的方式解决此问题,这里有两个选项
一般来说,如果你可以更好地使用Read Commited或Read Commited Snapshot隔离级别,那么Serializable不是一个好的扩展隔离级别。
同样在代码上生成增量ID最好留给具有不同机制的数据库以避免锁定。
如果你想拥有连续的订单号(为什么?有一些差距不应该是一个大问题,并且会为你节省很多麻烦),你可能会对订单号产生瓶颈。您可以让您的数据库端单线程并一次参加一个请求,这样您甚至不需要为此创建事务。但显然你会遇到可扩展性问题。
答案 1 :(得分:0)
我不是数据库专家,但在某些代码中可能会发生一些使用相同的表读/写。试试这个:
TransactionOptions transOptions = new TransactionOptions();
transOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
var orderNumber = 1;
Order order = null;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOptions))
{
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();
}
如果在此link和TransactionOptions& IsolationLevel。我希望这会对你有所帮助。