WITH(NOLOCK)与SET事务隔离级别的读取未提交


118

可能有人给我时,我应该使用一些指导WITH (NOLOCK),而不是SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

每种优点/缺点是什么?使用一种相对于另一种会遇到意外后果吗?

Answers:


105

他们是一样的东西。如果使用该set transaction isolation level语句,它将应用于连接中的所有表,因此,如果您只想nolock在一个或两个表上使用它;否则使用其他。

两者都会给你脏读。如果您对此表示满意,请使用它们。如果您不能进行脏读,请考虑snapshotserializable提示。


考虑REPEATABLE READ而不是SERIALIZABLE如果您不在乎幻像数据。SERIALIZABLE实际上是限制性的,几乎不应该使用(例如在某些关键的财务应用程序中除外)。
Kryptos



9

据我所知,唯一的区别是效应的范围,如斯特罗米所说。在表上提示NOLOCK,在会话上提示READ UNCOMMITTED。

至于可能发生的问题,全都与一致性有关。如果您在乎的话,请注意您会得到所谓的脏读,这可能会影响对不正确信息进行处理的其他数据。

我个人认为我没有从中看到任何问题,但这可能更多是由于我使用nolock的原因。您需要注意,在某些情况下可以使用它。场景中,您主要是向表中添加新数据,但后面有另一个过程来检查数据场景。这可能是可以的,因为主要流程不包括在读取过程中返回和更新行。

我也相信这些天您应该研究多版本并发控制。我相信他们在2005年添加了它,它通过为读者提供要使用的数据库快照来帮助阻止作者阻止读者。我将提供一个链接,并将进一步的研究留给读者:

MVCC

数据库隔离级别


+1虽然我没有进入READ_UNCOMMITTED了”“你应该”方面,肖恩很好地覆盖这个也有,你可以在SQL Server(由于页拆分)读取相同的行两次的情况。
Anon246

6

您不能在视图中使用“未提交设置事务隔离级别读”(实际上您只能在其中包含一个脚本),因此,如果应包括脏行,则必须使用(nolock)。


4

由于必须对每个表使用WITH(NOLOCK),因此在每个FROM或JOIN子句中写入它可能会很烦人。但是,将其称为“脏”读取有其原因。因此,您确实应该知道何时进行操作,而不要将其设置为会话范围的默认值。为什么?

忘记一个WITH(NOLOCK)可能无法在一个非常戏剧性的方式影响你的程序,但是做了脏读,你做在某些情况下希望可能会有所作为。

因此,如果允许选择的当前数据不正确,请使用WITH(NOLOCK),因为稍后可能会回滚。当您想提高性能时,通常使用此方法,而对应用程序上下文的要求使它冒着显示不一致数据的风险。但是,您或负责人必须权衡使用WITH(NOLOCK)的决定的利弊。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.