过去几个小时我一直在谷歌搜索答案,但没有找到答案,所以我希望有人能指出我正确的方向。
我想知道如何在TransactionScope中使用EF DbContext(代码优先)进行脏读。例如
DbContext context = new MyEntities();
using(TransactionScope scope = new TransactionScope())
{
context.SomeTable.Add(someObject);
context.SaveChanges();
var objects = context.SomeTable.Where(...).Select(...); //times out here on the read, because the write above locks the tables
//modify each object
context.SaveChanges();
scope.Complete(); //transaction is a success only if the entire batch succeeds
}
我尝试使用以下内容包装read调用:
using(TransactionScope scope2 = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions{IsolationLEvel = IsolationLevel.ReadUncommitted}))
{
var objects = context.SomeTable.Where(...).Select(...); //times out here on the
}
什么是正确的方法?
答案 0 :(得分:1)
它终于找到了我的问题所在:EF没有像TransactionScope
那样与L2S很好地集成。这意味着EF会为需要服务器的每个操作打开和关闭连接(保存更改或查询)。
这可以获得分布式事务和分布式死锁。
要解决此问题,请手动打开和关闭EF StoreConnection
,以确保在交易期间只有一个连接。
答案 1 :(得分:1)
您可以像这样设置TransactionScope的IsolationLevel ......
var transactionOptions = new System.Transactions.TransactionOptions();
transactionOptions.Timeout = new TimeSpan(0, 0, 30);
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
using (var transactionScope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, transactionOptions))
{
...
}
答案 2 :(得分:0)
您可以在服务器上执行alter database your_db_name set READ_COMMITTED_SNAPSHOT on;
(可从SQLServer 2005获得),读者不会被读者阻止(假设在read committed
隔离级别读取事务)。