用简单的英语来说,使用某个东西的优缺点是什么?
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
在.NET应用程序和报表服务应用程序中进行查询?
用简单的英语来说,使用某个东西的优缺点是什么?
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
在.NET应用程序和报表服务应用程序中进行查询?
这种隔离级别允许脏读。一个事务可以看到其他事务未提交的更改。
为了保持最高级别的隔离性,数据库管理系统通常会在数据上获取锁,这可能会导致并发性的降低和大量的锁定开销。而这种隔离级别放宽了此属性。
您可能还想查看关于 READ UNCOMMITTED 的维基百科文章,其中包括一些例子和进一步阅读材料。
您可能还有兴趣查看Jeff Atwood在早期Stack Overflow时如何解决死锁问题的博客文章。根据Jeff:
但是使用
nolock
会有危险吗?理论上可能会导致读取无效数据。你会发现,一些数据库架构专家开始向你解释ACID理论,告诉你在使用nolock
时要小心谨慎,甚至告诉你要拉响建筑火灾警报。事实上,这些理论确实很可怕。但是,我认为:“在理论上,理论和实践没有区别,在实践中有。我永远不会推荐使用
nolock
作为一般的“什么都能解决”的万能药来解决数据库死锁问题。您应该首先尝试诊断问题的根源。但是,在实践中,只要您知道自己在做什么,向查询添加
nolock
从来没有导致问题... 只要您知道自己在做什么。
您可能要考虑的READ UNCOMMITTED
级别的替代方案是READ COMMITTED SNAPSHOT
。再次引用Jeff的话:
快照依赖于全新的数据更改跟踪方法...不仅仅是轻微的逻辑更改,它要求服务器在物理上处理数据的方式有所不同。一旦启用了这种新的数据更改跟踪方法,它就会创建每个数据更改的副本或快照。通过在争用时阅读这些快照而不是实时数据,读取操作不再需要共享锁,并且整体数据库性能可能会提高。
我最喜欢使用读取未提交数据(read uncommited)
的情景是用于调试事务内发生的问题。
在调试器下启动软件,当你逐行执行代码时,它会打开一个事务并修改您的数据库。在代码停止时,您可以打开查询分析器,将隔离级别设置为读取未提交数据并进行查询,以查看发生了什么。
您还可以使用它来查看长时间运行的过程是否卡住或使用count(*)
查询正确地更新了数据库。
如果您的公司喜欢制作过于复杂的存储过程,那这个功能非常实用。
这对于查看长时间插入查询的进度、进行任何粗略估计(比如 COUNT(*)
或粗略的 SUM(*)
)等非常有用。
换句话说,脏读取查询返回的结果只要你将其视为估算值并且不基于它们做出任何关键决策,就是可以接受的。
实现脏读或隔离级别0锁定,这意味着不会发出共享锁,并且不会尊重排他锁。 当设置此选项时,可以读取未提交或脏数据; 在事务结束之前,数据集中的值可以更改,行可以出现或消失。 此选项与在事务中所有SELECT语句的所有表上设置NOLOCK具有相同的效果。 这是四个隔离级别中最不限制的。
什么情况下可以使用READ UNCOMMITTED
?
好的情况:显示不断变化的总计的大型聚合报告。
有风险的情况:几乎所有其他情况。
好消息是,大多数只读报告都属于“好的”类别。
可以使用:
这基本上涵盖了商业智能部门在SSRS中执行的大多数操作。当然,例外情况是任何带有$符号的内容。许多人在处理与服务客户并赚取利润所需的相关核心指标时,比处理货币更加热衷于财务方面的工作。(我责怪会计师)。
有风险的情况:
任何到达详细级别的报告。如果需要该详细信息,则通常意味着每行都与决策相关。实际上,如果无法在不阻止的情况下拉取小的子集,则可能是因为正在编辑它。
历史数据。这很少有实际影响,但由于用户了解到不断变化的数据无法完美,因此他们对静态数据的看法不同。脏读不会对此造成伤害,但是双重读取偶尔会发生。既然您本来就不应该在静态数据上进行阻塞,为什么要冒险呢?
几乎所有供应具有写入功能的应用程序的内容。
即使是“好”的情况也不行。
NOLOCK
。select item from things with (UPDLOCK)
这样获取数据来处理它。在那里放一个快速超时,以便如果无法快速获取锁定,它会告诉用户正在进行编辑。这不仅可以保护您免受用户的影响,还可以保护您免受开发人员的影响。唯一的麻烦是,您必须开始考虑超时以及如何在UI中处理它。 - Adamantish关于报告,我们在所有报告查询中使用它,以防止查询拖慢数据库。我们之所以能够这样做,是因为我们正在获取历史数据,而不是最新的微秒级数据。
在源数据很少发生变化的情况下,使用 READ_UNCOMMITTED。
在知道源数据可能在获取操作期间发生更改时,请勿使用 READ_UNCOMMITTED。
READ UNCOMMITTED
也是可以接受的。 - Adamantish它可以用于简单的表格,例如仅插入审计表中,在这种情况下,没有对现有行进行更新,也没有对其他表格的外键引用。插入是一个简单的插入操作,没有或很少可能回滚。
我现在总是使用READ UNCOMMITTED。它速度快,问题最少。当使用其他隔离级别时,你几乎总会遇到一些阻塞问题。
只要你使用自动增量字段并稍微注意插入操作,那么你就不用担心阻塞问题了。
使用READ UNCOMMITED可能会出现错误,但老实说,确保你的插入操作是完全正确的非常容易。唯一需要注意的是从SELECT语句中获取结果的插入/更新操作(在这里使用READ COMMITTED,或确保脏读不会引起问题)。
所以,采用脏读(特别是对于大型报告),你的软件将运行更加顺畅...
READ UNCOMMITTED
,你可能会重复读取某些行,或者漏掉整个行。如果在读取过程中出现页面拆分,则可能会丢失整块数据。只有当结果的准确性不重要时,才应使用WITH(NOLOCK)
。 - Ian Boyd