简体   繁体   English

在EF4中使用NOLOCK提示?

[英]Using NOLOCK Hint in EF4?

We're evaluating EF4 and my DBA says we must use the NOLOCK hint in all our SELECT statements. 我们正在评估EF4,我的DBA说我们必须在所有SELECT语句中使用NOLOCK提示。 So I'm looking into how to make this happen when using EF4. 所以我正在研究如何在使用EF4时实现这一点。

I've read the different ideas on how to make this happen in EF4, but all seem like a work around and not sanctioned by Microsoft or EF4. 我已经阅读了有关如何在EF4中实现这一目标的不同想法,但所有这些似乎都是一种解决方案而不是微软或EF4批准的。 What is the "official Microsoft" response to someone who wants their SELECT statement(s) to include the NOLOCK hint when using LINQ-to-SQL / LINQ-to-Entities and EF4? 当使用LINQ-to-SQL / LINQ-to-Entities和EF4时,希望他们的SELECT语句包含NOLOCK提示的人的“官方Microsoft”响应是什么?

By the way, the absolute best information I have found was right here and I encourage everyone interested in this topic to read this thread. 顺便说一下,我发现的绝对最好的信息就在这里 ,我鼓励每个对这个主题感兴趣的人阅读这个主题。

Thanks. 谢谢。

NOLOCK = "READ UNCOMMITTED" = dirty reads NOLOCK =“READ UNCOMMITTED”=脏读

I'd assume MS knows why they chose the default isolation level as "READ COMMITTED" 我假设MS知道为什么他们选择默认隔离级别为“READ COMMITTED”

NOLOCK, in fact any hint, should be used very judiciously: not by default. NOLOCK,实际上是任何提示,都应该非常明智地使用:默认情况下不是这样。

Your DBA is a muppet. 你的DBA是一个布偶。 See this (SO): What can happen as a result of using (nolock) on every SELECT in SQL Sever? 看到这个(SO): 在SQL Sever中的每个SELECT上使用(nolock)会导致什么结果? . If you happen to work at a bank, or any institution where I may have an account please let me know so I can close it. 如果您碰巧在银行或我可能拥有帐户的任何机构工作,请告诉我,以便我可以关闭它。

I'm a developer on a tools team in the SQL org at Microsoft. 我是Microsoft的SQL组织中的工具团队的开发人员。 I'm in no way authorized to make any official statement, and I'm sure there are people on SO who know more about these things than I do. 我绝对没有授权做任何正式声明,我确信有些人比我更了解这些事情。 Nevertheless, I'll offer a friendly rule of thumb, along the theme of "Premature optimization is the root of all evil": 尽管如此,我将提供一个友好的经验法则,主题是“过早优化是万恶之源”:

Don't use NOLOCK (or any other query hint for that matter), until you have to. 在你必须这样做之前,不要使用NOLOCK(或任何其他查询提示)。 If you have a select statement which has a decent query plan, and it runs fine when there is very little other load on the system, but then it slows down when other queries are accessing the same table, try adding some NOLOCK hints. 如果你有一个具有合适查询计划的select语句,并且当系统上的其他负载很少时它运行正常,但是当其他查询访问同一个表时它会变慢,请尝试添加一些NOLOCK提示。 But always understand that when you do, you run the risk of getting inconsistent data. 但总是要明白,当你这样做时,你就冒着获得不一致数据的风险。 If you are writing some mission critical app that does online banking or controls an aircraft, this may be unacceptable. 如果您正在编写一些关键任务应用程序,可以进行网上银行业务或控制飞机,这可能是不可接受的。 However, for many applications the perf speedup is worth the risk. 然而,对于许多应用而言,性能加速值得冒险。 Evaluate on a case-by-case basis, though. 但是,根据具体情况进行评估。 Don't just use them willy nilly all over the place. 不要只是无处不在地使用它们。

If you do choose to use NOLOCK, I have blogged a solution in C# using extension methods, so that you can easily change a LINQ query to use NOLOCK hints. 如果您确实选择使用NOLOCK,我使用扩展方法在C#中发布了一个解决方案 ,以便您可以轻松更改LINQ查询以使用NOLOCK提示。 If you can adapt this to EF4, please post your adaptation. 如果您能将其改编为EF4,请发布您的改编。

EF4 does not currently have a built in way to do it IF ef4 is generating all your queries. 如果ef4生成所有查询,EF4目前没有内置方法。

There are ways around this such as using stored procedures or a more extended inline query model, however, this can be time consuming to say the least. 有很多方法可以解决这个问题,例如使用存储过程或更加扩展的内联查询模型,但是,至少可以说这很费时间。

I believe (and I don't speak for Microsoft on this) that caching is Microsoft's intended solution for lightening the load on the server in EF4 sites. 我相信(我不会就微软发言)缓存是微软旨在减轻EF4网站服务器负担的预期解决方案。 Having read uncommitted (or nolock) built into a framework would create unpredictable issues for the expected behaviour of EF4 when 2 contexts are run at the same time. 读取未提交(或nolock)内置到框架中会在同时运行2个上下文时为EF4的预期行为创建不可预测的问题。 That doesn't mean your situation needs that level of concurrency. 这并不意味着您的情况需要这种并发级别。

It sounds like you were asked for nolock on ALL selects. 这听起来好像你被要求在所有选择上nolock。 While I agree with earlier poster that this can be dangerous if you have ANY transactions that need to be transactions, I don't agree that automatically makes the DBA a muppet. 虽然我同意早先的海报,如果你有任何需要交易的交易,这可能是危险的,我不同意自动使DBA成为一个布偶。 You might just be running a CMS which is totally cool for dirty reads. 你可能只是在运行一个CMS,这对脏读来说非常酷。 You can change the ISOLATION LEVEL on your whole database which can have the same effect. 您可以更改整个数据库的ISOLATION LEVEL,这可以产生相同的效果。

The DBA may have recommended nolock for operations that were ONLY selects (which is fine, especially if there's an ORM being misuesd and doing some dodgy data dumps). DBA可能已经为仅仅选择的操作推荐了nolock(这很好,特别是如果有一个ORM被误导并做了一些狡猾的数据转储)。 The funniest thing about that muppet comment is that Stack Overflow itself runs SQL server in a READ UNCOMMITTED mode. 关于该muppet评论最有趣的事情是Stack Overflow本身以READ UNCOMMITTED模式运行SQL服务器。 Guess you need to find somewhere else to get answers for your problems then? 猜猜你需要在其他地方找到解决问题的答案吗?

Talk to your DBA about the posibility of setting this on a database level or consider a caching strategy if you only need it in a few places. 与您的DBA讨论在数据库级别设置此功能的可能性,或者如果您只在少数几个地方需要它,请考虑缓存策略。 The web is stateless after all so concurrency can often be an illusion anyway unless you address it direclty. 毕竟网络是无状态的,所以除非你直接解决,否则并发往往是一种错觉。

Info about isolation levels 有关隔离级别的信息

Having worked with EF4 for over a year now, I will offer that using stored procedures for specific tasks is not a hack and absolutely necessary for performance under certain situations. 在EF4工作了一年多之后,我将提出使用存储过程执行特定任务不是黑客攻击 ,在某些情况下对性能绝对必要。

Our platform gets a lot of traffic through our web site, APIs and ETL data feeds. 我们的平台通过我们的网站,API和ETL数据源获得大量流量。 We use EF primarily on our web side, but also for some back-end processes. 我们主要在我们的网络端使用EF,但也用于某些后端流程。 Sometimes EF does a great job with its query generation, sometimes it is terrible. 有时EF在查询生成方面做得很好,有时它很糟糕。 You need to look at the queries being generated, load them into query analyzer, and decide whether you might be better off writing the operation in another way (stored procedure, etc.). 您需要查看正在生成的查询,将它们加载到查询分析器中,并决定是否可以更好地以其他方式编写操作(存储过程等)。

If you find that you need to make data available via EF and need NOLOCKs , you can always create views with the NOLOCK hints included, and expose the view to EF instead of the underlying table. 如果您发现需要通过EF提供数据并需要NOLOCKs ,则始终可以创建包含NOLOCK提示的视图 ,并将视图公开给EF而不是基础表。 The same can be done with Stored Procedures. 存储过程也可以这样做。 These methods are probably a bit easier when you are using the Code First approach. 使用Code First方法时,这些方法可能会更容易一些。

But I think that one mistake a lot of people make with EF is believing that the EF object model has to map directly to the physical (table) model in the database. 但我认为很多人用EF做的一个错误就是认为EF对象模型必须直接映射到数据库中的物理(表)模型。 It doesn't and this is where your DBA comes into play. 它没有,这就是你的DBA发挥作用的地方。 Let him design your physical model and you work together to abstract your logical data model which is mapped to your object model in EF. 让他设计你的物理模型,然后你一起工作来抽象你的逻辑数据模型,它被映射到EF中的对象模型。

Although this would be a major PITA to do, you can always drop your SQL in a stored procedure and get the functionality you need (or are forced into). 虽然这将是一个主要的PITA,但您始终可以在存储过程中删除SQL并获得所需的功能(或被强制使用)。 It's definitely a hack though! 这绝对是一个黑客!

I know this isn't an answer to your question, but I just wanted to throw this in. 我知道这不是你问题的答案,但我只想把它扔进去。

It seems to me that this is (at least partially) the DBA's job. 在我看来,这是(至少部分)DBA的工作。 It's fine to say that an application should behave a certain way, and you can and should certainly attempt to program it the way that he would like. 可以说应用程序应该以某种方式运行,并且您当然可以并且应该尝试以他希望的方式对其进行编程。

The only way to be sure though, is for the DBA to work on the application with you and construct the DB surface that he would like to present to the app. 唯一可以确定的方法是让DBA与您一起处理应用程序并构建他想要呈现给应用程序的数据库表面。 If he wants critical tables to be queried as READ UNCOMMITTED, then he should help to provide a set of stored procedures with the correct access and isolation level. 如果他希望将关键表作为READ UNCOMMITTED进行查询,那么他应该帮助提供一组具有正确访问和隔离级别的存储过程。

Relying on the application code to construct every ad-hoc query correctly is not a scalable approach. 依靠应用程序代码来正确构建每个ad-hoc查询并不是一种可扩展的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM