8

我们正在评估 EF4,我的 DBA 说我们必须在所有 SELECT 语句中使用 NOLOCK 提示。所以我正在研究如何在使用 EF4 时实现这一点。

我已经阅读了有关如何在 EF4 中实现这一点的不同想法,但所有这些似乎都是一种变通方法,并且不受 Microsoft 或 EF4 的认可。在使用 LINQ-to-SQL / LINQ-to-Entities 和 EF4 时,对于希望他们的 SELECT 语句包含 NOLOCK 提示的人,“微软官方”的回应是什么?

顺便说一句,我找到的绝对最好的信息就在这里,我鼓励对这个主题感兴趣的每个人阅读这个主题。

谢谢。

4

6 回答 6

30

NOLOCK = "READ UNCOMMITTED" = 脏读

我假设 MS 知道他们为什么选择默认隔离级别为“READ COMMITTED”

NOLOCK,实际上是任何提示,都应该非常明智地使用:默认情况下不是。

您的 DBA 是一个布偶。请参阅此(SO):在 SQL Sever 中的每个 SELECT 上使用 (nolock) 会发生什么?. 如果您碰巧在银行或我可能有帐户的任何机构工作,请告诉我,以便我关闭它。

于 2010-01-26T18:55:32.280 回答
11

我是 Microsoft SQL org 工具团队的开发人员。我无权发表任何官方声明,而且我确信 SO 上有些人比我更了解这些事情。尽管如此,我将提供一个友好的经验法则,主题是“过早的优化是万恶之源”:

除非必须,否则不要使用 NOLOCK(或任何其他查询提示)。如果你有一个查询计划不错的 select 语句,并且当系统上的其他负载非常少时它运行良好,但是当其他查询访问同一个表时它会变慢,请尝试添加一些 NOLOCK 提示。但请始终理解,当您这样做时,您会冒着获得不一致数据的风险。如果您正在编写一些执行网上银行或控制飞机的关键任务应用程序,这可能是不可接受的。然而,对于许多应用程序来说,性能加速是值得冒险的。不过,请根据具体情况进行评估。不要只是在所有地方随意使用它们。

如果您确实选择使用 NOLOCK,我在 C# 中使用扩展方法编写了一个解决方案,以便您可以轻松更改 LINQ 查询以使用 NOLOCK 提示。如果您可以将此改编为 EF4,请发布您的改编。

于 2010-07-30T07:07:06.397 回答
9

如果 ef4 正在生成您的所有查询,则 EF4 目前没有内置方法。

有一些方法可以解决这个问题,例如使用存储过程或更扩展的内联查询模型,但是,至少可以说这可能很耗时。

我相信(我不代表微软)缓存是微软为减轻 EF4 站点中的服务器负载而设计的解决方案。当同时运行 2 个上下文时,已读取内置于框架中的未提交(或未锁定)将为 EF4 的预期行为产生不可预知的问题。这并不意味着您的情况需要这种级别的并发性。

听起来您被要求对所有选择进行 nolock 。虽然我同意之前的海报,如果您有任何需要成为交易的交易,这可能会很危险,但我不同意这会自动使 DBA 成为木偶。您可能只是在运行一个非常适合脏读的 CMS。您可以更改整个数据库的隔离级别,这可以产生相同的效果。

DBA 可能已经为仅选择的操作推荐了 nolock(这很好,特别是如果有一个 ORM 被误用并进行一些狡猾的数据转储)。关于那个布偶评论最有趣的是 Stack Overflow 本身以 READ UNCOMMITTED 模式运行 SQL Server。猜猜你需要找到其他地方来为你的问题找到答案吗?

与您的 DBA 讨论在数据库级别设置它的可能性,或者如果您只在几个地方需要它,请考虑缓存策略。毕竟网络是无状态的,所以除非你直接解决它,否则并发通常可能是一种错觉。

有关隔离级别的信息

于 2011-01-03T03:31:31.223 回答
3

使用 EF4 已经一年多了,我将提出,将存储过程用于特定任务并不是一种黑客行为,而且对于某些情况下的性能是绝对必要的。

我们的平台通过我们的网站、API 和 ETL 数据源获得大量流量。我们主要在 Web 端使用 EF,但也用于一些后端进程。有时 EF 在其查询生成方面做得很好,有时它很糟糕。您需要查看正在生成的查询,将它们加载到查询分析器中,并决定是否最好以另一种方式(存储过程等)编写操作。

如果您发现需要通过 EF 和需要提供数据NOLOCKs,则始终可以创建NOLOCK包含提示的视图,并将视图公开给 EF 而不是基础表。存储过程也可以这样做。当您使用 Code First 方法时,这些方法可能会更容易一些。

但我认为很多人对 EF 犯的一个错误是认为 EF 对象模型必须直接映射到数据库中的物理(表)模型。它没有,这就是您的 DBA 发挥作用的地方。让他设计您的物理模型,然后您一起工作以抽象出映射到 EF 中的对象模型的逻辑数据模型。

于 2013-01-17T13:30:10.390 回答
2

尽管这将是一个主要的 PITA,但您始终可以将 SQL 放入存储过程中并获得您需要(或被迫使用)的功能。这绝对是一个黑客!

于 2012-05-07T20:26:44.610 回答
-1

我知道这不是你问题的答案,但我只是想把它扔进去。

在我看来,这是(至少部分地)DBA 的工作。可以说应用程序应该以某种方式运行,您可以而且当然应该尝试按照他想要的方式对其进行编程。

但是,唯一可以确定的方法是让 DBA 与您一起处理应用程序并构建他想呈现给应用程序的 DB 表面。如果他希望关键表被查询为 READ UNCOMMITTED,那么他应该帮助提供一组具有正确访问和隔离级别的存储过程。

依靠应用程序代码正确地构造每个即席查询并不是一种可扩展的方法。

于 2010-01-26T17:23:37.663 回答