Entity Framework和事务隔离级别

35

我正在使用Entity Framework 4.0。现在我需要在读取或写入表时限制对该表的访问。这可能与事务隔离级别有关。

我该怎么做?

更新:

这是我的代码:

using (var db = new MyDb())
{
    using (TransactionScope scope = new TransactionScope())
    {
        var item = db.MyItems.Single(x => x.Id == 5);
        item.Price = 12;
        db.SaveChanges();
        scope.Complete(); 
    }
}

然而,当我在using (TransactionScope scope内部的任意一行设置断点,并且停在那里时,我去Sql Server Management Studio执行一个选择查询(甚至是更新!)从使用事务的表中,出于某种原因,我没有得到错误。但为什么?它不应该允许我在事务执行时读取数据。


重复的问题:https://dev59.com/c2jWa4cB1Zd3GeqPrYjy? - James Gaunt
1个回答

44

默认情况下,一个事务具有 Serializable 的 IsolationLevel。Serializable 是最高级别的隔离级别。这要求在任何其他事务被允许在数据上操作之前,该事务必须完成。

它有以下限制:

  • 语句不能读取已被其他事务修改但尚未提交的数据。
  • 没有其他事务可以修改当前事务已读取的数据,直到当前事务完成。
  • 其他事务不能插入新行,并使其键值落在当前事务中任何语句所读取的键范围内,直到当前事务完成。

这是一篇很好的博客文章,解释了如何使用 Entity Framework 进行事务:Entity Framework 事务范围示例

更新

在使用 Code First 创建的数据库中,Entity Framework 6 默认的 IsolationLevel 更改为 READ_COMMITTED_SNAPSHOT,这可能允许更多的可扩展性和更少的死锁。请参阅 EF 6 的未来规格


<<在允许任何其他事务之前>>那我不需要做任何其他的事情吗?你为什么说“任何其他事务”?可能会出现没有其他事务而只是一个查询,比如 select * from my_table - Alan Coromano
2
Serializable是最高的事务级别。它允许易失性读取,但不允许修改。我不知道这是否完全覆盖了您的方案,因为您还想禁止阅读。如果您通过实体框架运行命令,它将始终使用事务。如果您手动执行Sql查询,则必须手动将其放入TransactionScope中。 - Wouter de Kort
我在C#代码中没有手动使用SQL查询,所以我不需要使用TransactionScope,对吗? - Alan Coromano
EF 将使用默认的事务范围。只有在需要自定义设置时才需要使用自定义 TransactionScope。 - Wouter de Kort
@WouterdeKort 如何在Entity Framework中设置自定义事务范围和TransactionScopeAsyncFlowOption - 3 rules
我认为Wouter上面已经解释了为什么你没有看到错误。但是,TransactionScope的这篇文章表明,如果两个线程尝试修改相同的实体,则仍然可能存在并发问题:http://www.ladislavmrnka.com/2012/09/entity-framework-and-pessimistic-concurrency/ - andrew pate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接