说白了,使用的缺点和优点是什么

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

在.NET应用程序和报告服务应用程序的查询中?


当前回答

什么时候可以使用READ UNCOMMITTED?

经验法则

好:大的汇总报告显示不断变化的总数。

风险:几乎所有的事情。

好消息是,大多数只读报告都属于“好”类别。

更多细节…

可以使用它:

几乎所有面向用户的当前非静态数据(例如年迄今销售额)汇总报告。 它的误差幅度(可能小于0.1%)远低于其他不确定性因素,如输入错误或只是记录数据的随机时间。

这可能涵盖了商业智能部门在SSRS中所做的大部分工作。当然,任何前面有$符号的东西都是例外。许多人对金钱的热情远远超过了服务客户和产生金钱所需的相关核心指标。(我责怪会计)。

当风险

Any report that goes down to the detail level. If that detail is required it usually implies that every row will be relevant to a decision. In fact, if you can't pull a small subset without blocking it might be for the good reason that it's being currently edited. Historical data. It rarely makes a practical difference but whereas users understand constantly changing data can't be perfect, they don't feel the same about static data. Dirty reads won't hurt here but double reads can occasionally be. Seeing as you shouldn't have blocks on static data anyway, why risk it? Nearly anything that feeds an application which also has write capabilities.

即使是OK场景也不是OK。

是否有应用程序或更新过程使用大型单个事务?那些删除然后重新插入大量你正在报告的记录的?在这种情况下,不能对这些表使用NOLOCK。

其他回答

我现在总是使用READ UNCOMMITTED。速度快,问题少。当使用其他隔离时,你几乎总是会遇到一些阻塞问题。

只要你使用自动递增字段,多注意一下插入,你就可以和阻塞问题说再见了。

你可以用READ uncommitted犯错误,但老实说,确保你的插入是完全证明是很容易的。使用选择结果的插入/更新只是你需要注意的事情。(此处使用READ COMMITTED,或确保脏读不会引起问题)

所以去脏读吧(特别是大报告),你的软件会运行得更流畅……

它可以用于简单的表,例如仅插入的审计表,其中没有对现有行进行更新,也没有对其他表进行fk。插入是一个简单的插入,没有或很少有回滚的机会。

这对于查看长插入查询的进度,进行粗略估计(如COUNT(*)或粗略SUM(*))等非常有用。

换句话说,脏读查询返回的结果是好的,只要您将它们视为估值,并且不基于它们做出任何关键决策。

此隔离级别允许脏读。一个事务可以看到其他事务所做的未提交的更改。

为了保持最高级别的隔离,DBMS通常需要对数据进行锁定,这可能会导致并发性损失和较高的锁定开销。此隔离级别将放松此属性。

你可能想要查看维基百科上关于READ UNCOMMITTED的文章,以获得一些例子和进一步的阅读。


您可能还会对Jeff Atwood的博客文章感兴趣,这篇文章讲述了他和他的团队在Stack Overflow早期是如何解决死锁问题的。杰夫说:

But is nolock dangerous? Could you end up reading invalid data with read uncommitted on? Yes, in theory. You'll find no shortage of database architecture astronauts who start dropping ACID science on you and all but pull the building fire alarm when you tell them you want to try nolock. It's true: the theory is scary. But here's what I think: "In theory there is no difference between theory and practice. In practice there is." I would never recommend using nolock as a general "good for what ails you" snake oil fix for any database deadlocking problems you may have. You should try to diagnose the source of the problem first. But in practice adding nolock to queries that you absolutely know are simple, straightforward read-only affairs never seems to lead to problems... As long as you know what you're doing.

您可能想要考虑的READ UNCOMMITTED级别的一个替代方案是READ COMMITTED SNAPSHOT。再次引用杰夫的话:

快照依赖于一种全新的数据变化跟踪方法…不仅仅是轻微的逻辑更改,它还要求服务器以不同的物理方式处理数据。一旦启用了这个新的数据更改跟踪方法,它就会为每个数据更改创建一个副本或快照。通过在争用时读取这些快照而不是实时数据,读取时不再需要共享锁,并且整体数据库性能可能会提高。

这将为您提供脏读,并显示尚未提交的事务。这是最明显的答案。我不认为仅仅为了加快阅读速度而使用这个方法是个好主意。如果使用良好的数据库设计,还有其他方法可以做到这一点。

注意到没有发生什么也很有趣。READ UNCOMMITTED不仅忽略其他表锁。它自己也不会产生任何锁。

假设您正在生成一个大型报告,或者正在使用一个大型且可能复杂的SELECT语句将数据迁移出数据库。这将导致在事务期间将共享锁升级为共享表锁。其他事务可以从表中读取数据,但是不可能进行更新。如果它是一个生产数据库,这可能是一个坏主意,因为生产可能完全停止。

如果使用READ UNCOMMITTED,则不会在表上设置共享锁。你可以从一些新的事务中获得结果,也可以不从表中插入数据的位置和SELECT事务读取的时间中获得结果。如果发生页面分割,您还可能获得相同的数据两次(数据将被复制到数据文件中的另一个位置)。

因此,如果在执行SELECT操作时可以插入数据对你来说非常重要,READ UNCOMMITTED可能是有意义的。您必须考虑到您的报告可能包含一些错误,但如果它基于数百万行,并且在选择结果时只更新了其中的少数行,那么这可能是“足够好”的。由于不能保证行的唯一性,您的事务也可能一起失败。

更好的方法可能是使用SNAPSHOT ISOLATION LEVEL,但您的应用程序可能需要进行一些调整才能使用它。其中一个例子是,如果您的应用程序对一行采用排他锁以防止其他人读取它,并在UI中进入编辑模式。快照隔离级别也会带来相当大的性能损失(特别是在磁盘上)。但是你可以通过硬件来解决这个问题。:)

您还可以考虑恢复数据库的备份,以用于报告数据或将数据加载到数据仓库中。