【发布时间】:2014-10-13 13:32:47
【问题描述】:
我已经研究了两天的交易,也许我在收集了这么多信息后遗漏了一些明显的东西。这里的目标是阻止同时请求。如果condition 为真,则插入数据,之后condition 将为假。同时请求都会在插入数据之前检查condition,然后都会尝试插入数据。
public async Task<ActionResult> Foo(Guid ID)
{
Debug.WriteLine("entering transaction scope");
using (var transaction = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable },
TransactionScopeAsyncFlowOption.Enabled
))
{
Debug.WriteLine("entered transaction scope");
var context = new DbContext();
Debug.WriteLine("querying");
var foo = context.Foos.FirstOrDefault(/* condition */);
Debug.WriteLine("done querying");
context.Foos.Add(new Foo());
/* async work here */
Debug.WriteLine("saving");
context.SaveChanges();
Debug.WriteLine("saved");
Debug.WriteLine("exiting transaction scope");
transaction.Complete();
Debug.WriteLine("exited transaction scope");
return View();
}
}
这是使用 Fiddler 一次执行两个请求时的调试输出:
进入交易范围 进入交易范围 查询 完成查询 进入交易范围 进入交易范围 查询 完成查询 保存 保存 已保存 System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的第一次机会异常 退出交易范围 退出交易范围这是我对代码应该如何工作的理解:
- 需要具有可串行化隔离级别的事务,以防止幻读。
- 我不能使用
DbContext.Database.Connection.BeginTransaction,执行查询时会抛出错误:当分配给命令的连接处于挂起的本地事务中时,ExecuteReader 要求该命令具有事务。
该命令的 Transaction 属性尚未初始化。 -
TransactionScope在使用基于任务的异步时通常会导致问题。 http://entityframework.codeplex.com/discussions/429215 但是,.NET 4.5.1 添加了额外的构造函数来处理这个问题。 How to dispose TransactionScope in cancelable async/await? - EF 6 改进了事务支持,但我仍在使用 EF 5。 http://msdn.microsoft.com/en-us/data/dn456843.aspx
很明显,它并没有像我想要的那样工作。使用TransactionScope 可以实现我的目标吗?还是我必须升级到 EF 6?
【问题讨论】:
标签: c# asp.net-mvc entity-framework entity-framework-5 transactionscope