当前位置: 首页 > 编程日记 > 正文

SQL Server中SELECT会真的阻塞SELECT吗?

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

而且从最常见的锁模式的兼容性表,我们可以看到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,如下所示

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

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

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

在锁表(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了。

PS:上面是个人结合一些知识和理解,做的一些肤浅的判断与分析,如果不对的地方,敬请指正!

参考资料:

Database System Implementaion

转载于:https://www.cnblogs.com/kerrycode/p/6250606.html

相关文章:

appium IOS真机测试

看了 http://blog.csdn.net/today520/article/details/36378805 的文章&#xff0c;终于在真机上面测试成功。 由于没有开发者账号&#xff0c;不能发布应用到机器上面。所以就用了网易新闻的客户端来测试 没有开发者账号&#xff0c;貌似不能真正的开始测试。只能启动一下客户…

siwft 写时复制 Copy-On-Write

写时复制 Copy-On-Write 1 定义 在siwft 标准库中&#xff0c;Array&#xff0c;Dictionary&#xff0c;Set这样的集合类型是通过写时复制来实现的。 import Foundationvar a1 [1,2,3]; var a2 a1;// 将a1 复制给 a2&#xff0c;地址打印结果是相同的// 0x1--0x2--0x3 pri…

超越技术分析_超越技术面试

超越技术分析by Jaime J. Rios由Jaime J. Rios 超越技术面试 (Transcending the Technical Interview) “Wow. What a chastening and shameful experience that was.”“哇。 那真是一种令人st目结舌的经历。” This was my immediate mental reaction after I completed my…

轻松获取LAMP,LNMP环境编译参数配置

轻松获取LAMP&#xff0c;LNMP环境编译参数配置 作者:Mr.Xiong /分类:系统管理 字号&#xff1a;L M S大家是否遇到过去了新公司&#xff0c;公司内的LAMP&#xff0c;LNMP等所有的环境都是配置好的&#xff08;已经在提供服务了&#xff09;&#xff0c;公司又没有留下部署文档…

java内存分配--引用

栈内存 对象地址 堆内存 存放属性 public class TestDemo{ public static void main(String args[]){ Person perA new Person(); //出现new百分之百就是要申请堆内存 perA.name"王强"&#xff1b; //perA 地址存放在栈内存中&#xff0c;同一块内存只能存…

iOS NSObject对象内存大小

NSObject内存大小 类的本质是结构体 无须赘述 struct NSObject { Class isa; };一个类对象的实例大小是8个字节 之所以打印出的16个字节&#xff0c;是因为一个NSObject 最小开辟16个字节 NSObject *obj [[NSObject alloc]init];// class_getInstanceSize 这是runtime 获…

客户端渲染 服务端渲染_这就是赢得客户端渲染的原因

客户端渲染 服务端渲染A decade ago, nearly everyone was rendering their web applications on the server using technologies like ASP.NET, Ruby on Rails, Java, and PHP.十年前&#xff0c;几乎每个人都使用ASP.NET&#xff0c;Ruby on Rails&#xff0c;Java和PHP等技术…

java多线程三之线程协作与通信实例

多线程的难点主要就是多线程通信协作这一块了&#xff0c;前面笔记二中提到了常见的同步方法&#xff0c;这里主要是进行实例学习了&#xff0c;今天总结了一下3个实例&#xff1a; 1、银行存款与提款多线程实现&#xff0c;使用Lock锁和条件Condition。 附加 &#xff1a;…

Java8中Lambda表达式的10个例子

Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 Java代码 //Before Java 8: new Thread(new Runnable() { Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); …

OC的对象的分类

OC的对象分类 一 oc的对象分类主要分为3种 1 instance 对象&#xff1a; 实例对象就是通过alloc 出来的对象&#xff0c;一个类每一次的alloc都会产生一个新的实例对象 StudentA *a [[StudentA alloc]init];StudentA *b [[StudentA alloc]init];// 打印结果如下 地址是明显…

如何在国内上medium_在Medium上写作的风格指南

如何在国内上mediumAfter spending more than 1,000 hours writing and editing stories for our Medium publication, I’ve decided to create this living style guide for contributors. Feel free to use it for your publication as well.在花了1000多个小时为我们的《中…

C# webform上传图片并生成缩略图

其实里面写的很乱&#xff0c;包括修改文件名什么的都没有仔细去写&#xff0c;主要是想记录下缩略图生成的几种方式 &#xff0c;大家明白就好! 1 void UpImgs()2 {3 if (FileUpload1.HasFile)4 {5 string fileContentType FileUpload1.Pos…

ios中的自动释放池

自动释放池中是否有虑重功能 1 autoreleasepool { 2 UIView *view [UIView alloc] init] autorelease]; 3 [view autorelease]; 4 } 这样写在自动释放池的队列中是两个对象还是一个对象&#xff0c;就是说把view加到自动释放池的队列时&#xff0c;队列本身是…

arch linux安装_如何从头开始安装Arch Linux

arch linux安装by Andrea Giammarchi由Andrea Giammarchi In this article, youll learn how to install Arch Linux from scratch… and in about 5 minutes. So lets get to it.在本文中&#xff0c;您将学习如何从头开始安装Arch Linux&#xff0c;大约需要5分钟。 因此&am…

CoreCRM 开发实录 —— Profile

再简单的功能&#xff0c;也需要一坨代码的支持。Profile 的编辑功能主要就是修改个人的信息。比如用户名、头像、性别、电话……虽然只是一个编辑界面&#xff0c;但添加下来&#xff0c;涉及了6个文件的修改和7个新创建的文件。各种生成的和手写的代码&#xff0c;共有934行之…

iOS KVO 的实现原理

KVO 的实现原理 一 原理 1.KVO是基于runtime机制实现的 2.当某个类的属性对象第一次被观察时&#xff0c;系统就会在运行期动态地创建该类的一个派生类&#xff0c;在这个派生类中重写基类中任何被观察属性的setter 方法。派生类在被重写的setter方法内实现真正的通知机制 …

利用UltimateAndroid框架进行快速开发

UltimateAndroid是一套集成了许多现有优秀的Android开源类库并将之组合成一个整体的Android快速开发框架。框架目前主要包含的功能有View Injection,ORM,异步网络请求和图片加载&#xff0c;自动化脚本测试,磁盘LRU等功能.同时提供了类似于TripleDes、Webview快速设置、Md5处理…

溢出内容菜单_停止过度使用溢出菜单

溢出内容菜单by Daniel Burka丹尼尔伯卡(Daniel Burka) 停止过度使用溢出菜单 (Stop the overuse of overflow menus) You know those obscure menu buttons on apps and websites that reveal even more menu options? They usually have an ellipsis “…” or an arrow ▼…

KVC 和 KVO

KVC 键值编码 全称是Key-value coding&#xff0c;翻译成键值编码。它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制。 1.通过key&#xff08;成员变量的名称&#xff09;设置value&#xff08;成员变量的值&#xff09; - (void)setValue:(…

datasnap的客户端回传机制

最近&#xff0c;学习XE6下的DataSnap回叫技术编译代码&#xff0c;体会如下&#xff1a;第一篇 服务器与客户端回叫 从Delphi2010开始&#xff0c;DataSnap支持回叫&#xff08;Call Back&#xff09;机制。这样&#xff0c;在调用耗时较长的方法时&#xff0c;通过回叫机制…

Block 底层1

Block 本质来讲是OC 对象&#xff0c;其内部有一个isa指针。 1 Block 的声明 一言以蔽之&#xff1a; returnType &#xff08; ^blockName&#xff09;(parameterTypes) ^returnType (parameters) {}; returnType 返回的类型 可以为Void,为Void的时候可以省略^blockName …

从零学web前端_从零到前端英雄(第2部分)

从零学web前端This article is part two of the “From Zero to Front-end Hero” series. In part one, you learned how to create layouts with HTML and CSS as well as some best practices. In part two, we will focus on learning JavaScript as a standalone language…

jdk8飞行记录器配置

jdk8提供了jmc工具,应该比visualvm厉害吧 下面贴一份tomcat的配置,自己留个备份,把下面的内容粘贴到tomcat setenv.sh就可以了 nowdaydate %Y%m%d_%H%M%S test -d ../gclogs || mkdir ../gclogsif [ -r "$CATALINA_BASE/bin/setenv_custom.sh" ]; then. "$CATAL…

petaPar培训文档

自己写的实验室程序文档&#xff0c;方便后来者。 转载于:https://www.cnblogs.com/daijkstra/p/3972167.html

Block 底层值__Block修饰符

__Block 修饰符 Block 想要改变外部的变量&#xff0c;必须要用__Block 来修饰自动变量。 根据内存地址可以看出来&#xff0c;__block 所修饰的变量&#xff0c;将外部的变量在栈中的内存地址放到了堆中。 // auto 自动变量的内存分配在栈区域 stack__block int meters 100…

体检系统前端源码_给您的前端进行健康检查

体检系统前端源码by Ewa Mitulska-Wjcik伊娃米图尔斯卡(EwaMitulska-Wjcik) 给您的前端进行健康检查 (Give your Front End a Health Check) You’ve built out all your user stories and your app is working. Now’s it’s ready to submit as done, so you can move on wi…

1-runtime的Method,IMP,Property,ivar

基础定义 objc-750 的tar包 objc-private.h 定义 typedef struct objc_class *Class; typedef struct objc_object *id;#if __OBJC2__ typedef struct method_t *Method; typedef struct ivar_t *Ivar; typedef struct category_t *Category; typedef struct property_t *ob…

【编程题目】左旋转字符串 ☆

26.左旋转字符串&#xff08;字符串&#xff09;题目&#xff1a;定义字符串的左旋转操作&#xff1a;把字符串前面的若干个字符移动到字符串的尾部。如把字符串 abcdef 左旋转 2 位得到字符串 cdefab。请实现字符串左旋转的函数。要求时间对长度为 n 的字符串操作的复杂度为 O…

10、同步机制遵循的原则_我要遵循的10条原则

10、同步机制遵循的原则by Haseeb Qureshi由Haseeb Qureshi 我要遵循的10条原则 (10 Principles I Want to Live By) I just came home from a vow of silence at a meditation center in northern California. It’s a strange feeling coming back to city life after five …

2-Runtime objc_object objc_class

一 NSObject NSObject是OC 中的基类&#xff0c;除了NSProxy其他都继承自NSObject interface NSObject <NSObject> { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-interface-ivars"Class isa OBJC_ISA_AVAILABILITY; #pragma …