SQL Server如何一次性配置NOLOCK使其对所有查询生效?
SQL Server 能否全局一次声明NOLOCK免逐表加提示
SQL Server 原生不支持use all with (nolock)这类批量给所有关联表挂载NOLOCK提示的语法,但可以通过等价的会话配置实现接近预期的效果,具体说明如下:
等效实现方案
通过设置当前查询会话的事务隔离级别,一次配置即可让当前会话后续所有查询自动应用和NOLOCK完全一致的读取规则,无需逐表手动添加锁提示:
- 在会话开头执行一次配置命令,将当前会话的隔离级别切换到
READ UNCOMMITTEDSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; - 配置生效后,当前会话后续执行的所有普通查询中,凡是没有手动指定其他锁提示的表,都会自动跳过共享锁、允许读取未提交的脏数据,和逐表添加
WITH (NOLOCK)的实际效果完全等价。 - 实际写法参考:
-- 仅需执行一次的会话级设置 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -- 后续多表关联查询无需逐表加NOLOCK SELECT * FROM T1 JOIN T2 ON T1.id = T2.t1_ref JOIN T3 ON T2.id = T3.t2_ref JOIN T4 ON T3.id = T4.t3_ref;
关键注意点
- 该设置仅会话级生效:关闭当前查询窗口、新建数据库连接后,设置会自动失效,不会影响其他用户、其他业务应用对数据库的访问。
- 不存在服务器/数据库级的一键全局NOLOCK开关:微软未开放这类配置项,核心原因是NOLOCK带来的读脏数据风险极高,一旦全局开启,所有接入数据库的业务都会面临数据一致性隐患,生产环境绝对不建议通过修改数据库默认隔离级别这类方式强行让全局查询默认带NOLOCK。
- 行为差异说明:逐表书写的
WITH (NOLOCK)是单表粒度的锁提示,仅作用于你指定的单张表;而会话级隔离级别设置会覆盖当前查询语句里所有未手动指定锁规则的表,绝大多数日常开发场景下,两者没有可感知的行为差异。 - 优先级规则:如果查询中某张表手动指定了其他锁提示(比如
WITH (UPDLOCK)、WITH (HOLDLOCK)),会优先以手动指定的提示为准,不受会话隔离级别设置的影响。
内容的提问来源于stack exchange,提问作者user14665886
相关产品推荐
相关产品推荐

