返回顶部
首页 > 资讯 > 数据库 >SQL Server中的SELECT会不会阻塞SELECT
  • 596
分享到

SQL Server中的SELECT会不会阻塞SELECT

2024-04-02 19:04:59 596人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关SQL Server中的SELECT会不会阻塞SELECT的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言在sql Server中,我们知道一

这篇文章给大家分享的是有关SQL Server中的SELECT会不会阻塞SELECT的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

前言

sql Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.TEST WHERE OBJECT_ID =1 这个查询语句,其申请、释放的锁资源的过程如下所示:

SQL Server中的SELECT会不会阻塞SELECT

而且从最常见的锁模式的兼容性表,我们可以看到IS锁与S锁都是兼容的,也就是说SELECT查询是不会阻塞SELECT查询的。


现有的授权模式

请求的模式

IS

S

U

IX

SIX

X

意向共享 (IS)

共享 (S)

更新 (U)

意向排他 (IX)

意向排他共享(SIX)

排他 (X)

但是在某些特殊场景。你会看到SELECT语句居然“阻塞”SELECT操作,那么SQL Server中SELECT会真的阻塞SELECT操作吗?我们先构造测试的案例场景,那么先准备测试数据吧

CREATE TABLE TEST (OBJECT_ID INT, NAME VARCHAR(8));
 
CREATE INDEX PK_TEST ON TEST(OBJECT_ID) 
 
 
DECLARE @Index INT =0;
 
WHILE @Index < 20
BEGIN
 INSERT INTO TEST
 SELECT @Index, 'kerry';
 
 SET @Index = @Index +1;
END

在会话窗口A中,执行下面SQL语句,模拟一个UPDATE语句正在执行

BEGIN TRANSACTioN
 
 UPDATE dbo.TEST SET NAME='Kerry' WHERE OBJECT_ID=1;
 --ROLLBACK;

会话窗口B中,执行下面的SQL语句

SELECT * FROM dbo.TEST WHERE OBJECT_ID=1

会话窗口C中,执行下面的SQL语句

SELECT * FROM dbo.TEST WHERE OBJECT_ID=1

我实验的场景下,会话窗口A的会话ID为85,会话窗口B的会话ID为90,会话窗口C的会话ID为87,如下所示

SQL Server中的SELECT会不会阻塞SELECT

如下所示,你会看到SELECT语句“阻塞”了SELECT语句,即会话90“阻塞”了会话87, 它们的等待事件都为LCK_M_S,也就是说它们都在等待获取共享锁,也许你会置疑这个SQL是否有问题,那么我们使用SP_WHO来查看,你会发现也是如此,如下所示:

SQL Server中的SELECT会不会阻塞SELECT

如下所示,我们会发现会话ID为90 、87的会话都在等待类型为RID,Resource为1:24171:1的共享锁

SQL Server中的SELECT会不会阻塞SELECT

其实应该说,会话87、90都在等待RID对象的共享锁,我们知道共享锁与意向共享锁都是兼容的,所以SELECT是不会阻塞SELECT的,那么又怎么解释这个现象呢?在宋大神的指点下,粗略的翻了Database System Implementaion这本书(很多原理性知识,看起来相当吃力)。里面介绍了在锁表(lock table)以及Element Info、Handling Lock Requests、Handling Unlocks等概念,有一个有意思的图所示,

SQL Server中的SELECT会不会阻塞SELECT

在锁表(lock table)里,elements info里的锁的申请是在一个类似队列的结构。先进先出机制,所以当会话90先进入队列,它在等待共享锁(S), 会话87也进入队列等待共享锁(S),而且它在会话90的后面(即会话90这个elements info后面的Next指针指向会话87会话的事务),由于两个会话都被阻塞,这两个会话的Wait字段都是Yes,由于内部某些机制,会话87显示阻塞它的会话为90(这个是我个人臆测,实际具体原因有待考究),实质阻塞的源头还是会话85. 当会话85释放排它锁(X)后,会话队列根据下面几个原则来处理解锁(Handling Unlocks):

1: First-come-first-served: Grant the lock request that has been waiting the longest. This strategy guarantees no starvation, the situation where a transaction can wait forever for a lock

先来先服务(队列的原则):授予锁等待时间最长的锁请求,这种策略保证不会饿死(翻译感觉不贴切),即一个事务不会永远等待锁的情况。

2. Priority to shared locks: First grant all the shared locks waiting. Then,grant one update lock, if there are any waiting. Only grant an exclusive lock if no others are waiting. This strategy can allow starvation, if a transaction is waiting for a U or X lock.

共享锁优先,首先授予所有等待共享锁(S),然后授予其中一个更新锁(U),如果有其它类型等待,只有在没有其它锁等待时,才授予排它锁、这一策略允许等待更新锁或排它锁的事务饿死(结束)

3. Priority to upgrading: If there is a transaction with a U lock waiting to upgrade it to an X lock, grant that first. Otherwise, follow one of the other strategies mentioned.

锁升级优先,如果有一个持有共享锁(U)等待升级Wie排他锁(X),那么先授予它排它锁,否则采用前面已经提到的策略中的一个。

按照这些原则,当会话85释放了排它锁(X)后,调度器(Scheduler)应该会根据先后顺序依次授予会话90、87共享锁(S),两者的阻塞会几乎同时消失。 这个可以也可以通过实验进行一个大概的推断, 在上面实验中,你可以手工取消90会话的查询操作,然后再查看阻塞情况,就会发现会话87被85阻塞了。这个阻塞的源头就变成了85,而不是90了。

感谢各位的阅读!关于“SQL Server中的SELECT会不会阻塞SELECT”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

您可能感兴趣的文档:

--结束END--

本文标题: SQL Server中的SELECT会不会阻塞SELECT

本文链接: https://lsjlt.com/news/59590.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SQL Server中的SELECT会不会阻塞SELECT
    这篇文章给大家分享的是有关SQL Server中的SELECT会不会阻塞SELECT的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言在SQL Server中,我们知道一...
    99+
    2024-04-02
  • css加载会不会造成阻塞
    这篇文章给大家介绍css加载会不会造成阻塞,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。可能大家都知道,js执行会阻塞DOM树的解析和渲染,那么css加载会阻塞DOM树的解析和渲染吗?接下来,我就来对css加载对DOM...
    99+
    2023-06-08
  • 在 goroutine 中添加 select default 语句导致通道阻塞
    在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天编程网就整理分享《在 goroutine 中添加 selec...
    99+
    2024-04-05
  • Golang channel为什么不会阻塞的原因详解
    正文 最近在学通道channel,发现一个简单的demo: package main import "fmt" func main() { chanInt := make(c...
    99+
    2024-04-02
  • Redis的快照为什么不会阻塞其他请求
    今天就跟大家聊聊有关Redis的快照为什么不会阻塞其他请求,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。为什么这么设计(Why's THE ...
    99+
    2024-04-02
  • 为何某些操作会引发通道阻塞,而另一些则不会?
    对于一个Golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《为何某些操作会引发通道阻塞,而另一些则不会?》,主要介绍了,希望对大家的知...
    99+
    2024-04-04
  • 一文带你学会MySQL的select语句
    目录SQL概述SQL背景知识SQL语言排行榜SQL 分类SQL语言的规则与规范基本规则SQL大小写规范 (建议遵守)注释命名规则(暂时了解)数据导入指令基本的SELECT语句SELECT...SELECT ......
    99+
    2024-04-02
  • SQL SERVER中SELECT和SET赋值有什么区别
    这篇文章主要介绍了SQL SERVER中SELECT和SET赋值有什么区别,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。SELECT...
    99+
    2024-04-02
  • SQL SERVER中SELECT和SET赋值异同点有哪些
    本文小编为大家详细介绍“SQL SERVER中SELECT和SET赋值异同点有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“SQL SERVER中SELECT和SET赋值异同点有哪些”文章能帮...
    99+
    2024-04-02
  • sql中的select distinct怎么使用
    在SQL中,SELECT DISTINCT用于返回唯一不重复的值。通过在SELECT语句中添加DISTINCT关键字,可以筛...
    99+
    2024-04-16
    sql
  • SQL Server中如何使用Select into复制数据到新表
    小编给大家分享一下SQL Server中如何使用Select into复制数据到新表,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去...
    99+
    2024-04-02
  • sql中select语句的使用示例
    这篇文章主要介绍了sql中select语句的使用示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。SQL SELECT 语句SEL...
    99+
    2024-04-02
  • sql中insert select的用法是什么
    在SQL中,INSERT SELECT语句用于将查询结果插入到另一个表中。语法如下: INSERT INTO table2 ...
    99+
    2024-03-01
    sql
  • SQL中select distinct的作用是什么
    在SQL中,SELECT DISTINCT语句的作用是返回唯一的值,即去除重复的数据行。 当我们使用SELECT语句从表中检...
    99+
    2024-04-09
    SQL
  • SQL中select distinct的用法是什么
    SELECT DISTINCT用于查询唯一值。它能够在查询结果中排除重复的行,只返回不同的行。 语法格式如下: SELECT...
    99+
    2024-04-09
    SQL
  • sql中update select的用法是什么
    在SQL中,UPDATE SELECT语句用于更新表中的数据,同时使用SELECT语句来指定要更新的行。 基本语法如下: UPDAT...
    99+
    2024-04-09
    sql
  • SQL中select语法结构是怎样的
    这篇文章给大家分享的是有关SQL中select语法结构是怎样的的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。SQL中select语句的语法结构是:“SELECT sel...
    99+
    2024-04-02
  • SQL中show和select的区别是什么
    在SQL中,SHOW和SELECT是两个不同的命令,用于不同的目的。1. SHOW命令用于显示数据库中的元数据信息,例如数据...
    99+
    2023-09-22
    SQL
  • 使用select 语句进行查询时,变量名不加引号会导致的错误
      假设一个数据库表中存有如下信息,其中login_uuid字段数据类型为varchar 当我们查找999这条数据时,使用这样的查询语句 查询出来的结果也是,我们所期望的 但是,如果没有在999处加引号,会出现错误 ...
    99+
    2017-05-03
    使用select 语句进行查询时,变量名不加引号会导致的错误
  • 如何在SQL中的SELECT语句中使用REPLACE
    在SQL中,可以使用REPLACE函数来替换SELECT语句中的特定字符或字符串。语法如下:SELECT REPLACE(c...
    99+
    2023-09-26
    SQL
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作