【发布时间】:2011-06-07 17:06:02
【问题描述】:
我有一个使用 Linq-to-SQL 作为数据访问层的 ASP.NET MVC 3 Web 应用程序。每次调用 Details 操作时,我都会尝试增加 Views 字段,但如果两个人碰巧同时点击操作,我会在 db.SubmitChanges() 上收到“未找到或更改行”错误。
public ActionResult Details(int id)
{
DataClassesDataContext db = new DataClassesDataContext();
var idea = db.Ideas.Where(i => i.IdeaPK == id).Single();
idea.Views++;
db.SubmitChanges();
return View(new IdeaViewModel(idea));
}
我可以在我的 .dbml(数据模型)中将 Views 字段的 UpdateCheck 设置为“从不”,这样可以消除错误,但是可以使用相同的 Views 计数更新创意记录两次。即
First instance of Details action gets idea record with Views count of 1.
Second instance of Details action gets idea record with Views count of 1.
First instance increments Views to 2
First instance commits
Second instance increments Views to 2
Second instance commits
Result: Views field is 2
Expected Result: Views field should be 3
我研究过使用 TransactionScope,但我从两个调用之一中得到以下死锁错误:
事务(进程 ID 54)是 在锁定资源上死锁 另一个过程并被选为 僵局的受害者。重新运行 交易。
当我将操作更新为如下所示时:
public ActionResult Details(int id)
{
DataClassesDataContext db = new DataClassesDataContext();
using (var transaction = new TransactionScope()){
var idea = db.Ideas.Where(i => i.IdeaPK == id).Single();
idea.Views++;
db.SubmitChanges();
return View(new IdeaViewModel(idea));
}
}
我还尝试使用 TransactionScopeOptions 增加 TransactionScope 超时,但这似乎没有帮助(但我可能还必须在其他地方设置它)。我可能可以通过使用 db.ExecuteQuery 在单个 SQL 命令中执行增量来解决此示例,但我试图弄清楚如何使这项工作发挥作用,所以我会知道在更复杂的场景中该怎么做(我想执行单个事务中的多个命令)。
【问题讨论】:
标签: c# asp.net-mvc linq-to-sql architecture concurrency