15

Sql Server之旅——第十二站 对锁的初步认识

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA%3D%3D&%3Bmid=2654078630&%3Bidx=5&%3Bsn=46f6a0052c05909f599444cd85d28a17
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

作为一个开发人员,锁机制也是我们程序员必须掌握的东西,很久之前在学习锁的时候,都是教科书上怎么说,然后我怎么背,缺少一个工具让我们眼见为实。。。如果这样的话,学习一个东西就很容易忘记。。。因为这些都是你背诵过来的。。。这篇的话我就来分享一个工具来帮助我们学习锁。

一:到底都有哪些锁

学习锁之前,必须要知道锁大概有几种???通常情况下作为码农我们只需知道如下几个锁即可。。。

1.S(Share)锁

为了方便理解,我们可以直接这么认为,当在select的时候在表,数据页,记录上加上共享锁。

2.X(Exclusive) 锁

我们在delete数据的时候会在记录上附加X锁,我们知道X锁并不与其他的锁兼容。如果其他的锁与其遭遇,就会处于等待,后续我们再说。

3.U(Update)锁

顾名思义,我们在Update的时候,在寻找记录的过程中,会逐一的给记录附加U锁,如果找到了目标记录的话,则会将U锁转化为X锁。。。

4.I (Intent)锁

这个就是所谓的意向锁,一般都是给表和数据页附加的锁,好处就是防止被其他连接修改表结构。

二:天下无敌的SqlServer Profile

这个工具我想大家都明白,它的监视能力真的是无所不能。。。锁的痉挛状态也全在它的掌握之中。

1. 首先我做一个Person表,Name字段设定4000字节,这样一个数据页可以容纳2条数据,如下图:

DROP TABLE dbo.Person
CREATE TABLE Person(ID INT IDENTITY,NAME CHAR(4000) DEFAULT 'aaaaa')
--插入6条,生成3个数据页
INSERT INTO dbo.Person DEFAULT VALUES
go 6

2. 下面我们看看数据在数据页的分布情况。

BJFzI3y.png!web

3. 然后我们开启Profile,在“事件选择”的Events中选择”Lock:Acquired“和”Lock:Released“ ,然后运行,如下图:

FRfiQzi.png!web

三:使用测试数据

1. 首先我执行一个简单的 SELECT * FROM dbo.Person,看看表/数据页/记录的加锁情况。

zMJZRni.png!web

从图中可以看到,select执行的大概步骤如下:

第一步:给表(Object)加上IS(意向共享锁)。

第二步:先给1:78号数据页加IS锁,扫描78号数据页,然后释放IS锁。

第三步:同样的道理扫描之后的数据页。

第四步:最后释放表的IS锁,结束整个锁流程。

看完上面的一系列的Lock:Acquired 和 Lock:Released的话,你有没有发现一个问题,不是说好给记录(RID)加上S锁么???这里没加,

是因为引擎进入78号数据页的时候,未发现它存在IU锁或者IX锁。。。所以。。。这个属于锁的组合,后续会说。

2. 接下来用UPDATE dbo.Person SET NAME='bbbbb' WHERE ID=3来看看update的整个过程,乍一看,Profile捕获到的记录还是比较多的,下面具体看图:

JnIJzmB.png!web

第一步:给表(Object)加上IX锁,

第二步:给数据页(1:78)数据页分配IU锁。然后开始逐一扫描78号数据页的RID记录,进入前就Acquired,退出后就Released,当扫描完78号数据页的所有RID后描完78号数据页的所有RID后,再释放78号数据页的IU锁,进入下一个数据页。。。

第三步:我们发现ID=3是在89号数据页上,当引擎扫到该RID之后,我们观察到89号的数据页由IU锁变成了IX锁,并且把1:89:0(slot为0的记录)由U锁变成X锁,变成X锁后,就排斥了其他所有的锁,这时候就可以进行Update操作了。

第四步:后面就继续90号数据页,步骤类似,第二步和第三步。

不知道细心的你有没有发现,在Released Object之前我们才释放1:89:0的X锁,然后释放89号数据页的IX锁,这说明什么???说明这个 Update是贯穿于这个事务的,不像Select操作中,扫完一个数据页就释放一个数据页。

3. 最后再看一个DELETE FROM dbo.Person WHERE ID=3 的操作。

IBZBz2E.png!web

大概扫了一下上面的图,或许你感觉和Update操作大差不差,会扫描数据页中的每个记录并加上U锁。当在1:89:0槽位中找到了目标记录后,然后将U锁转化为X锁,具体可以参考Update。

好了,最最单纯的DML操作都展示给你看了...我们知道生产环境没有这么简单,但是你有此宝贝,再多动动脑子就:cow::nose:了。。。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK