我们正在评估EF4,我的DBA说我们必须在所有SELECT语句中使用NOLOCK提示。所以我在研究如何在使用EF4时实现这一点。
我已经阅读了关于如何在EF4中实现这一点的不同想法,但所有这些似乎都是一种解决方法,而不是微软或EF4批准的。在使用LINQ-to-SQL / LINQ-to-Entities和EF4时,希望他们的SELECT语句包含NOLOCK提示的人的“官方Microsoft”响应是什么?
顺便说一下,我发现的绝对最佳信息是right here,我鼓励所有对这个主题感兴趣的人阅读这个主题。
感谢。
答案 0 :(得分:30)
NOLOCK =“READ UNCOMMITTED”=脏读
我假设MS知道为什么他们选择默认隔离级别为“READ COMMITTED”
NOLOCK,实际上任何提示都应该非常明智地使用:默认情况下不是。
你的DBA是一个布偶。见(SO):What can happen as a result of using (nolock) on every SELECT in SQL Sever?。如果您碰巧在银行或我可能拥有帐户的任何机构工作,请告诉我,以便我可以关闭它。
答案 1 :(得分:11)
我是Microsoft的SQL组织中的工具团队的开发人员。我绝对没有授权做任何正式声明,我确信有些人比我更了解这些事情。尽管如此,我将提供一个友好的经验法则,主题为“过早优化是万恶之源”:
不要使用NOLOCK(或任何其他查询提示),直到必须。如果你有一个具有合适查询计划的select语句,并且当系统上的其他负载很少时它运行正常,但是当其他查询访问同一个表时它会变慢,请尝试添加一些NOLOCK提示。但总是要明白,当你这样做时,你就冒着获得不一致数据的风险。如果您正在编写一些关键任务应用程序,可以进行网上银行业务或控制飞机,这可能是不可接受的。然而,对于许多应用而言,性能加速值得冒险。但是,根据具体情况进行评估。不要只是无处不在地使用它们。
如果您确实选择使用NOLOCK,我在C#中使用扩展方法blogged a solution,这样您就可以轻松更改LINQ查询以使用NOLOCK提示。如果您可以将其改编为EF4,请发布您的改编。
答案 2 :(得分:9)
如果ef4生成所有查询,EF4目前没有内置方法。
有很多方法可以解决这个问题,例如使用存储过程或更加扩展的内联查询模型,但至少可以说这很费时间。
我相信(我不会就微软发言)缓存是微软旨在减轻EF4网站服务器负担的预期解决方案。读取未提交(或nolock)内置到框架中会在同时运行2个上下文时为EF4的预期行为创建不可预测的问题。这并不意味着您的情况需要这种并发水平。
听起来你被要求在所有选择中使用nolock。虽然我同意早先的海报,如果你有任何需要交易的交易,这可能是危险的,我不同意自动使DBA成为一个布偶。你可能只是在运行一个CMS,这对脏读来说非常酷。您可以更改整个数据库的ISOLATION LEVEL,这可以产生相同的效果。
DBA可能已经推荐nolock用于仅选择的操作(这很好,特别是如果ORM被误导并做了一些狡猾的数据转储)。关于该muppet评论最有趣的事情是Stack Overflow本身以READ UNCOMMITTED模式运行SQL服务器。猜猜你需要在其他地方找到解决问题的答案吗?
与您的DBA讨论在数据库级别设置此功能的可行性,或者如果您只在少数几个地方需要它,请考虑缓存策略。毕竟网络是无状态的,所以除非你直接解决,否则并发往往是一种错觉。
答案 3 :(得分:3)
现在已经使用EF4超过一年了,我将提出使用存储过程执行特定任务不是黑客,并且在某些情况下对性能绝对必要。
我们的平台通过我们的网站,API和ETL数据源获得了很多的流量。我们主要在我们的网络端使用EF,但也用于某些后端流程。有时EF在查询生成方面做得很好,有时它很糟糕。您需要查看正在生成的查询,将它们加载到查询分析器中,并决定是否可以更好地以其他方式编写操作(存储过程等)。
如果您发现需要通过EF提供数据且需要NOLOCKs
,则始终可以创建包含NOLOCK
提示的视图,并将视图公开给EF而不是基础表。存储过程也可以这样做。使用Code First方法时,这些方法可能会更容易一些。
但我认为很多人用EF做的一个错误就是相信EF对象模型必须直接映射到数据库中的物理(表)模型。它没有,这就是你的DBA发挥作用的地方。让他设计你的物理模型,你一起工作来抽象你的逻辑数据模型,它被映射到EF中的对象模型。
答案 4 :(得分:2)
虽然这将是一个主要的PITA,但您始终可以将SQL放在存储过程中并获得所需的功能(或被强制使用)。这绝对是一个黑客!
答案 5 :(得分:-1)
我知道这不是你问题的答案,但我只想把它扔进去。
在我看来,这是(至少部分)DBA的工作。可以说应用程序应该以某种方式运行,并且您当然可以并且应该尝试按照他希望的方式对其进行编程。
唯一可以确定的方法是让DBA与您一起处理应用程序并构建他想要呈现给应用程序的数据库表面。如果他希望将关键表作为READ UNCOMMITTED进行查询,那么他应该帮助提供一组具有正确访问和隔离级别的存储过程。
依靠应用程序代码正确构建每个ad-hoc查询并不是一种可扩展的方法。