gpt4 book ai didi

c# - 事务死锁,如何设计得当?

转载 作者:太空狗 更新时间:2023-10-29 17:39:25 24 4
gpt4 key购买 nike

所以我正在处理这个 Entity Framework 项目,该项目将用作 DAL 的一种,在运行压力测试时(通过 Thread() 对实体启动几个更新),我得到了这些:

_innerException = {"Transaction (Process ID 94) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction."}

这是我如何实现类方法的一些示例:

public class OrderController
{

public Order Select(long orderID)
{
using (var ctx = new BackEndEntities())
{

try
{
var res = from n in ctx.Orders
.Include("OrderedServices.Professional")
.Include("Agency")
.Include("Agent")
where n.OrderID == orderID
select n;
return res.FirstOrDefault();
}
catch (Exception ex)
{
throw ex;
}
}
}

public bool Update(Order order)
{
using (var ctx = new BackEndEntities())
{
try
{
order.ModificationDate = DateTime.Now;
ctx.Orders.Attach(order);
ctx.SaveChanges();
return true;
}
catch (Exception ex)
{
throw ex;
}
}
}
}

和:

public class AgentController
{

public Agent Select(long agentID)
{
using (var ctx = new BackEndEntities())
{
try
{
var res = from n in ctx.Agents.Include("Orders")
where n.AgentID == agentID
select n;
return res.FirstOrDefault();
}
catch (Exception ex)
{
throw ex;
}
}

}

public bool Update(Agent agent)
{
using (var ctx = new BackEndEntities())
{
try
{
agent.ModificationDate = DateTime.Now;
ctx.Agents.Attach(agent);
ctx.ObjectStateManager.ChangeObjectState(agent, System.Data.EntityState.Modified);
ctx.SaveChanges();
return true;
}
catch (Exception ex)
{
throw ex;
}
}
}
}

显然,这里的代码可能会更好,但我只是一个 EF 新手。但我认为我的问题是上下文的设计问题。

我记得这里有人提到,如果我的上下文不共享,我就不会遇到这些死锁问题。

这对我来说似乎不是“共享”的,因为我在每个方法中都使用了新的 BackEndEntities(),所以我必须改变什么才能使其更健壮?

此 DAL 将用于在互联网上公开的 Web 服务(在当然的代码审查之后),因此我无法控制它的压力有多大,并且许多不同的实例可能想要更新同一个实体。

谢谢!

最佳答案

造成这些死锁的原因不是您的代码,而是由于 EF 使用 SERIALIZABLE 作为默认的 TransactionScope 隔离级别。

SERIALIZABLE 是最受限制的锁定,这意味着您默认选择最受限制的隔离级别,并且您可以期待很多锁定!

解决方案是根据您要执行的操作指定另一个 TransactionScope。您可以用类似这样的内容包围您的 EF 操作:

using (var scope = new TransactionScope(TransactionScopeOption.Required, new 
TransactionOptions { IsolationLevel= IsolationLevel.Snapshot }))
{
// do something with EF here
scope.Complete();
}

阅读有关此问题的更多信息:

http://blogs.msdn.com/b/diego/archive/2012/04/01/tips-to-avoid-deadlocks-in-entity-framework-applications.aspx

http://blogs.u2u.be/diederik/post/2010/06/29/Transactions-and-Connections-in-Entity-Framework-40.aspx

http://blog.aggregatedintelligence.com/2012/04/sql-server-transaction-isolation-and.html

https://serverfault.com/questions/319373/sql-deadlocking-and-timing-out-almost-constantly

关于c# - 事务死锁,如何设计得当?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12166516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com