1

在过去的几个小时里,我一直在谷歌搜索答案,但还没有找到答案,所以我希望这里有人能指出我正确的方向。

我想知道如何在 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
}

我尝试使用以下内容包装读取调用:

using(TransactionScope scope2 = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions{IsolationLEvel = IsolationLevel.ReadUncommitted}))
{
    var objects = context.SomeTable.Where(...).Select(...); //times out here on the 
}

什么是正确的方法?

4

3 回答 3

1

它终于让我明白了问题所在:EF 没有TransactionScope像 L2S 那样很好地集成。这意味着 EF 为需要服务器的每个操作打开和关闭连接(保存更改或查询)。

这为您提供分布式事务和分布式死锁。

要解决此问题,请手动打开和关闭 EF StoreConnection,以确保在事务期间只有一个连接。

于 2012-12-08T14:13:22.830 回答
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))
{
...
}
于 2012-12-21T15:12:45.040 回答
0

您可以只alter database your_db_name set READ_COMMITTED_SNAPSHOT on;在服务器上执行(可从 SQLServer 2005 获得),并且读取器不会被写入程序阻塞(假设在read committed隔离级别读取事务)。

于 2012-12-07T23:20:40.077 回答