您现在的位置是:亿华云 > IT科技类资讯
SQLserver 的 Nolock 到底是怎样的无锁
亿华云2025-10-09 12:49:01【IT科技类资讯】6人已围观
简介一:背景1. 讲故事相信绝大部分用 SQLSERVER 作为底层存储的程序员都知道nolock关键词,即使当时不知道也会在踩过若干阻塞坑之后果断的加上nolock,但这玩意有什么注意事项呢?这就
一:背景
1. 讲故事
相信绝大部分用 SQLSERVER 作为底层存储的的到底程序员都知道 nolock 关键词,即使当时不知道也会在踩过若干阻塞坑之后果断的无锁加上 nolock,但这玩意有什么注意事项呢?的到底这就需要了解它的底层原理了。
二:nolock 的无锁原理
1. sql 阻塞还原
为了方便讲述,先创建一个 post 表,的到底插个 6 条记录,无锁参考代码如下:
CREATE TABLE post(id INT IDENTITY,的到底content char(4000))
GO
INSERT INTO dbo.post VALUES(aaa)
INSERT INTO dbo.post VALUES(bbb)
INSERT INTO dbo.post VALUES(ccc);
INSERT INTO dbo.post VALUES(ddd);
INSERT INTO dbo.post VALUES(eee);
INSERT INTO dbo.post VALUES(fff);这里为了简单我没有创建索引,所以会出现 Table Scan 的无锁情况,毕竟生产环境下的的到底sql也避免不了 Table Scan 和 Clustered Index Scan 的存在,接下来还原下阻塞场景,无锁开启两个 session 会话,的到底 session1 为正在运行的 update 事务, session2 为一个简单的 select 操作,这种场景下会导致 session2 阻塞,无锁参考代码如下:
session1BEGIN TRAN
UPDATE post SET content=xxxxx WHERE id=3session2SELECT * FROM post WHERE id=4从图中可以看到,的到底这个 select 已经阻塞 9 分钟了,无锁那为什么会被阻塞呢?的到底可以观察 SQLSERVER 内部的统计信息,比如锁相关的企商汇动态视图 sys.dm_tran_locks ,参考代码如下:
SELECT t.request_session_id,
CASE
WHEN t.resource_type = OBJECT THEN
OBJECT_NAME(t.resource_associated_entity_id)
WHEN t.resource_associated_entity_id = 0 THEN
/
ELSE
OBJECT_NAME(p.object_id)
END AS resource_name,
index_id,
t.resource_type,
t.resource_description AS description,
t.request_mode AS mode,
t.request_status AS status
FROM sys.dm_tran_locks AS t
LEFT JOIN sys.partitions AS p
ON p.hobt_id = t.resource_associated_entity_id
WHERE t.resource_database_id = DB_ID()从图中看,session55 准备在 1:489:0 这个槽位指向的记录上附加 S 锁时被阻塞,因为 1:489:0 已经被附加了 X 锁,很显然这个 X 锁是 update 给的。
上面给出的是一个 静态视图,为了方便显示动态视图,这里把 sql profile 开起来观察两个 session 给锁的过程,事件选择上如下所示:
将 sqlprofile 开启后,重新运行下刚才的两个会话,观察 profile 的走势,截图如下:
图中的注释已经说的非常清楚了,和 sys.dm_tran_locks 显示的一致,有了这些基础后接下来观察下如果加上 with (nolock) 会怎么样?
SELECT * FROM post(NOLOCK) WHERE id=4你会发现结果是可以出来的,那为什么可以出来呢?继续观察下 profile 即可。
从 session 55 的 lock 输出来看,with(nolock) 会对 post 表附加 Sch-S 架构稳定锁,以及分区中的 堆或BTree 附加S锁,亿华云 而不再对 PAGE 附加任何锁了,所以就不存在阻塞的情况,但肯定会引起脏读。
到这里基本上就是 nolock 的底层玩法了吧,不过也有一个注意点,nolock 真的不会引发阻塞吗? 接下来我们好好聊一聊。
3. nolock 真的无视阻塞吗
从 sqlprofile 观察锁的走势图来看,nolock 只是在上限为 page 页级别上做到无视,但在 page 之上就无法做到了,比如你看到的 Sch-S,可能有些朋友要问了,为什么要加上 Sch-S 锁呢?其实很简单,在 query 的过程中一定要保持架构稳定嘛,不能在 query 的过程中,post 表突然被删了,这样大家多尴尬。
接下来也可以做个简单的测试。
----- session 1
BEGIN TRAN
TRUNCATE TABLE post;
----- session 2
SELECT * FROM post(NOLOCK) WHERE id=4可以发现 nolock 查询也被阻塞了,原因就在于拿不到 post 表的 Sch-S 锁,因为 TRUNCATE 已经给 post 附加了 Sch-M 架构修改锁,那有没有数据支撑呢?继续用动态视图 sys.dm_tran_locks 观察便可。
三:总结
综上所述,云服务器nolock 也仅在 page 级别上畅通无阻,在某些情况下也会有阻塞情况的发生,由于无锁自然就会读到别的会话已修改但还未提交的记录,sqlserver 作为一个数据库应用程序,里面包含了大量的运行时统计信息,这些统计信息可以用 系统视图 和 动态视图 获取,完全可以基于它们做一个完善的 APM 监控。
很赞哦!(9)
相关文章
- a、变更前的公司证件扫描件(代码证或者营业执照)及联系人身份证复印件、变更后的公司证件扫描件(代码证或者营业执照)及新的联系人身份证复印件;身份证复印件需本人签名,公司证件复印件需加盖公章。
- 批量购买一口价域名的方法介绍
- 快速入门 Postcss 插件:自动转换 Px 到 Rem
- 对于老域名的挖掘,我们要怎么做呢?
- (4) 使用何种形式的域名后缀对网页搜索影响不大,但域名后缀也需要考虑方便用户记忆
- MySQL的慢SQL该怎么优化?
- 【鸿蒙开发】开发笔记-对象关系映射数据库
- CSS 边玩边学,这五个游戏让你对 CSS 的掌握更进一步!
- 公司名字不但要与其经营理念、活动识别相统一,还要能反映公司理念,服务宗旨、商品形象,从而才能使人看到或听到公司的名称就能产生愉快的联想,对商店产生好感。这样有助于公司树立良好的形象。
- 为什么MySQL不建议使用Delete删除数据?
站长推荐
2、根据用户基础选择访问提供程序。由于互联问题的存在,接入商的选择也非常重要,如果用户群主要在联通,尽量选择联通接入较好的接入商,如果用户群主要在电信,那么选择电信接入较好的接入商。如果用户组位于国家/地区,则选择更好的访问提供程序进行交互。
能利用闲置域名获利吗?闲置域名能不能短期投资吗?
一篇学会 C# Redis list 当作队列使用
Elasticsearch不会DSL没事,来试试SQL吧
.com域名是国际最广泛流行的通用域名,目前全球注册量第一的域名,公司企业注册域名的首选。国际化公司通常会注册该类域名。
四声母域名五声母域名近期有高价成交吗?
一套简单实用的SQL脚本,总有你需要的
域名价格竟然这么贵!细数知名天价域名