使用NOLOCK读取单个静态行。伤害是什么?

时间:2014-10-03 14:46:52

标签: sql sql-server deadlock

任何有DEADLOCK经验的人都可以开导我吗?

我读到它会导致日志文件损坏 - 可能吗?我认为MS永远不会这样做。如果"某些情况",就像我的,可以使用DEADLOCK,为什么不使用它呢?

我没有数据集,返回表格(就像Stack Overflow中的其他帖子一样)。我有一个带有ID select的SQL语句,它只返回一行,如:

 sqlstr = "SELECT Parameter1 FROM Companies WITH (NOLOCK) WHERE ID = 25

此外,此参数不会更改。但由于这是一个重载的as​​pnet应用程序(不是一个网站),我一次又一次地运行这种查询,每次SQL读取都会导致SQL服务器锁定。如果可能的话,我宁愿避免这种情况。

此站点中的每个帖子都涉及多个记录,记录集和脏读。我找不到任何关于"阅读单个记录的内容并没有随时改变"。

请问任何专家意见?

4 个答案:

答案 0 :(得分:0)

这个简单的select语句在默认事务隔离级别下没有任何锁定/ nolock提示时执行,在行上获得共享锁,这意味着其他用户也可以在此查询读取该行时读取该行。

另一方面,当您指定WITH (NOLOCK)查询提示时,它根本不会获得任何锁定。在这种情况下,其他用户也可以读取此行,但您可能正在读取脏行(尚未提交到磁盘并且正在被修改的数据)。

因此,在任何一种情况下,这个简单的选择都不会导致死锁。那么你应该问自己的问题是,用户是否能够看到脏数据?在大多数情况下,答案是否定的。

因此,不要担心使用此选择查询获取死锁。只要您使用默认事务隔离级别。在像seriallizable这样更严格的隔离级别中,select可以锁定其他用户,但在默认的隔离级别,你应该没问题。

答案 1 :(得分:0)

NOLOCK有两个主要缺点:它可以返回未提交的数据(您似乎并不担心这一点),并且在非常罕见的情况下它可能导致查询虚假地失败。永远不会NOLOCK导致物理数据库损坏。

考虑对仅读取数据的事务使用快照隔离。 SI下的读者不会锁定或阻止。 SI将它们从图片中删除。它为只读事务提供了完美的一致性。一定要找出缺点。

答案 2 :(得分:0)

这不值得。

NOLOCK经常被用作加速数据库读取的神奇方法,但我尽量避免使用它。

结果集可以包含尚未提交的行,这些行通常会在以后回滚。

错误或结果集可以为空,缺少行或多次显示同一行。

这是因为其他交易在您阅读的同时正在移动数据。

READ COMMITTED增加了一个额外的问题,即单个列中的数据被破坏,其中多个用户同时更改同一个单元格。

还有其他副作用,导致牺牲你希望首先获得的速度增加。

现在你知道了,再也不用了。

答案 3 :(得分:-1)

经过深入搜索并向许多专家提问后,我发现使用NOLOCK提示在这种情况下没有问题,但是没有建议。 NOLOCK没有错,但是当我使用sql2014时,我应该"应该"使用ISOLATION LEVEL选项。它是一种方法来代替NOLOCK。例如,对于导致死锁的巨大表选择:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION; 
SELECT * FROM HugeTable;
COMMIT TRANSACTION;

非常方便。

我有一个HugeTable和一个使用sqlAdapter和Radgrid来显示这些数据的Web表单。每当我运行这个报告时,尽管radgrid的索引和分页都很好,但它会导致死锁,这是有道理的。我将sqlAdapter的select语句更改为上面的句子,现在完美了。

最好的。