【问题标题】:Entity framework type of read lock实体框架类型的读锁
【发布时间】:2016-01-13 21:49:53
【问题描述】:

实体框架的默认读锁是什么,如何实现可重复读锁。

我在想,也许某处有一个全局设置,因此默认情况下会获取可重复读取类型的读锁,然后在 savechanges 启动后释放。

What is the default transaction isolation level in Entity Framework when I issue “SaveChanges()”?.这里说默认隔离级别是snapshot.如何改成可重复读取。

【问题讨论】:

  • 您将锁与事务隔离级别混淆了。此外,你为什么认为你需要一把锁?听起来您正在寻找悲观锁定,这对于单用户桌面应用程序以外的任何东西都是非常糟糕的做法。另一方面,乐观并发保证了正确性和可扩展性
  • 或者你可能试图通过锁来实现对象版本控制,或者至少是检出功能。你不能,因为检查记录以进行编辑与锁定无关 - 这是一个比锁定更复杂的更高级别的概念。在行本身上使用标志,或者更好的是,一个或多个单独的表与谁签出什么
  • 基本上,一旦我从一行中读取,我想确保在我当前的事务完成之前没有人更改该行。
  • 你认为你为什么需要它? SaveChanges 在内部使用事务,因此您不必担心丢失更改。如果您想使用长时间运行的事务作为快速而肮脏的结帐机制,您将产生无法修复的可伸缩性问题。在用户浏览网格或去喝咖啡时锁定行是防止应用程序为几个并发用户提供服务的可靠方法。
  • 无论如何,EF已经对事务使用可重复读取隔离级别。

标签: sql-server entity-framework


【解决方案1】:

Msdn 告诉默认隔离模式是依赖于数据库的。

它还提供了一个如何处理事务的示例,这是您需要从使用隔离模式 repeatable read 的等待中受益的内容。请注意,他们的示例有一个非常严重的缺陷,因为它会吞噬任何异常。

这是他们示例的固定版本。 context 应该是派生自 DBContext 的类的实例。

        using (var dbContextTransaction = 
            context.Database.BeginTransaction(
                System.Data.IsolationLevel.RepeatableRead))
        {
            try
            {
                // Your work here, then

                context.SaveChanges();
                dbContextTransaction.Commit();
            }
            catch
            {
                dbContextTransaction.Rollback();
                throw;
            }
        }

正如 Panagiotis Kanavos 所警告的那样,应尽可能避免这种锁定。它降低了可扩展性,增加了死锁风险,只要事务正在运行,就可能完全阻塞其他用户,...

try catch rollback 可能被认为是多余的,因为处置正在进行的 System.Data.SqlClient.SqlTransaction 会导致它回滚(using 将确保它被处置)。但由于具体事务可能属于其他类型,具体取决于所使用的数据存储,因此在发生故障时显式回滚它会更安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    相关资源
    最近更新 更多