如果两个请求在 ASP.NET MVC 应用程序中非常接近,我会使用以下代码出现竞争条件:
var workload = org.Workloads.SingleOrDefault(p => ...conditions...);
if (workload == null) {
workload = org.CreateWorkload(id);
}
workload
并且org
是 EntityFramework 对象。调用向CreateWorkload
数据库中的工作负载表添加一行。(我们确实应该在表上使用 UNIQUE 约束来强制执行此操作,但我现在不能因为表中有一些脏数据。SingleOrDefault
)当遇到多行时,对包含此代码的 Action 方法的后续调用会引发异常满足条件。
所以要解决这个问题,我想要lock
这些代码行。我不希望它按请求完成,使用静态锁定对象,因为这会减慢每个用户的网站速度。我想做的是Session.SyncRoot
用于锁定。IE
Workload workload;
lock (Session.SyncRoot)
{
workload = org.Workloads.SingleOrDefault(p => ...conditions...);
if (workload == null) {
workload = org.CreateWorkload(id);
}
}
但是,我不是 ASP.NET 专家,并且在文档和 ReSharper 中出现了一些警告标志,即它可以抛出 NotImplementedExceptions 或为 null。但是,测试表明这很好用。
那么,ASP.NET 专家,为此使用 Session.SyncRoot 有什么风险?作为替代方案,如果 Session.SyncRoot “真的很危险”,我可以在 Session 启动时在 Session 集合中分配一个锁对象来做同样的事情吗?