https://learn.microsoft.com/zh-cn/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
以上官方文档说NOLOCK 等效于 READUNCOMMITTED,不过我个人认为READUNCOMMITTED是针对整个会话而言,NOLOCK针对某表而言,就功能而言两者没有太大的区别
READUNCOMMITTED
指定允许脏读。 不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据。 允许脏读可能产生较多的并发操作,但其代价是读取以后会被其他事务回滚的数据修改。 这可能会使您的事务出错,向用户显示从未提交过的数据,或者导致用户两次看到记录(或根本看不到记录)。
READUNCOMMITTED 和 NOLOCK 提示仅适用于数据锁。 所有查询(包括那些带有 READUNCOMMITTED 和 NOLOCK 提示的查询)都会在编译和执行过程中获取 Sch-S(架构稳定性)锁。 因此,当并发事务持有表的 Sch-M(架构修改)锁时,将阻塞查询。 例如,数据定义语言 (DDL) 操作在修改表的架构信息之前获取 Sch-M 锁。 所有并发查询(包括那些使用 READUNCOMMITTED 或 NOLOCK 提示运行的查询)都会在尝试获取 Sch-S 锁时被阻塞。 相反,持有 Sch-S 锁的查询将阻塞尝试获取 Sch-M 锁的并发事务。
不能为通过插入、更新或删除操作修改过的表指定 READUNCOMMITTED 和 NOLOCK。 SQL Server 查询优化器忽略 FROM 子句中应用于 UPDATE 或 DELETE 语句的目标表的 READUNCOMMITTED 和 NOLOCK 提示。
备注:在 SQL Server 的未来版本中,将不再支持在 FROM 子句中使用应用于 UPDATE 或 DELETE 语句目标表的 READUNCOMMITTED 和 NOLOCK 提示。 请避免在新的开发工作上下文中使用这些提示,并计划修改当前使用它们的应用程序。
实验
会话1
CREATE TABLE testtable1 (h1 int,h2 char(200),h3 char(200))
begin transaction insert1
declare @i int
set @i=1
while @i<1000
begin
insert into testtable1 (h1,h2,h3)
values(@i,'hhhhhh2','hhhhhh3');
set @i=@i+1;
waitfor delay'00:00:01:00'
end
commit transaction insert1
会话2文章来源:https://www.toymoban.com/news/detail-526480.html
select count(*) from testtable1 with(nolock)
GO
select count(*) from testtable1
在会话1的事务提交之前,会话2执行几次的结果中,第一条命令select count() from testtable1 with(nolock)的结果会增加,比如10,11,12条记录这样子,但是select count() from testtable1的结果一直是0,说明with(nolock)确实读的是脏数据,如果会话2 with(nolock)给用户展示数据后,会话1回滚了,那么会话2 with(nolock)给用户展示的数据就是错误数据文章来源地址https://www.toymoban.com/news/detail-526480.html
到了这里,关于Sqlserver 中select with(nolock)等同于READUNCOMMITTED脏读的理解和实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!