S 锁与 X 锁,当前读与快照读!

数据库 MySQL
S 锁,英文为 Shared Lock,中文译作共享锁,有时候我们也称之为读锁,即 Read Lock。S 锁之间是共享的,或者说是互不阻塞的。

MySQL 中的锁还是蛮多的,在之前的文章中,松哥和大家介绍过 MySQL 中的 MDL 锁,今天我们再来看看 MySQL 中比较重要的两个锁:S 锁和 X 锁。

1. S 锁

S 锁,英文为 Shared Lock,中文译作共享锁,有时候我们也称之为读锁,即 Read Lock。S 锁之间是共享的,或者说是互不阻塞的。

当事务读取一条记录时,需要先获取该记录的 S 锁。

举个例子:

事务 T1 对记录 R1 加上了 S 锁,那么事务 T1 可以读取 R1 这一行记录,但是不能修改 R1,其他事务 T2 可以继续对 R1 添加 S 锁,但是不能添加 X 锁,只有当 R1 上面的 S 锁释放了,才能加上 X 锁。

举一个加 S 锁的例子,如下图:

此时,对于 id=1 的这条记录,只能读取不能修改了。假设在另外一个事务 T 中,执行如下 SQL 是没问题的,因为 S 锁是共享锁,S 锁和 S 锁之间是兼容的:

select * from user where id=1 lock in share mode;

但是如果执行如下 SQL 则会被阻塞,因为修改数据需要获取 X 锁,而 S 锁和 X 锁不兼容:

update user set username='javaboy' where id=1;

上面这个更新语句内部会获取 X 锁,对于一些手动添加了 X 锁的查询语句,也会阻塞,例如下面这个:

可以看到,这个 SQL 执行之后就被阻塞了。

2. X 锁

X 锁,英文为 Exclusive Lock,中文译作排他锁,有时候我们也称之为写锁,即 Write Lock。如同它的名字,X 锁是具有排他性的,即一个写锁会阻塞其他的 X 锁和 S 锁。

当事务需要修改一条记录时,需要先获取该记录的 X 锁。

举个例子:

事务 T1 对记录 R1 加上了 X 锁,那么事务 T1 即可以读取 R1 也可以修改 R1,而其他事务则不能对 R1 再添加任何锁,直到 T1 释放了 R1 上的锁。

如上文图示,锁定读的格式是这样的:

select .... for update;

3. 当前读与快照读

由上面这两种锁,又引申出来两种读:

3.1 快照读

快照读(SnapShot Read)是一种一致性不加锁的读,是 InnoDB 存储引擎并发如此之高的核心原因之一。

在可重复读的隔离级别下,事务启动的时候,就会针对当前库拍一个照片(快照),快照读读取到的数据要么就是拍照时的数据,即事务开启那一瞬间数据库中的数据,要么就是当前事务自身插入/修改过的数据。

我们日常所用的不加锁的查询,都属于快照读,这个我就不演示了。

3.2 当前读

与快照读相对应的就是当前读,当前读就是读取最新数据,而不是历史版本的数据,换言之,在可重复读隔离级别下,如果使用了当前读,也可以读到别的事务已提交的数据。

松哥举个例子:

MySQL 事务开启两个会话 A 和 B。

首先在 A 会话中开启事务并查询 id 为 1 的记录:

接下来我们在 B 会话中对 id 为 1 的数据进行修改,如下:

注意 B 会话不要开启事务或者开启了及时提交事务,否则 update 语句占用一把排他锁会导致一会在 A 会话中用锁时发生阻塞。

接下来,回到 A 会话中继续做查询操作,如下:

可以看到,A 会话中第一个查询是快照读,读取到的是当前事务开启时的数据状态,后面两个查询则是当前读,读取到了当前最新的数据(B 会话中修改后的数据)。

4. 小结

好啦,一个小小的知识点,日积月累,fighting!

责任编辑:武晓燕 来源: 江南一点雨
相关推荐

2022-02-17 21:13:08

MySQL架构体系

2022-12-27 10:02:38

MVCC机制Innodb

2023-02-23 10:32:52

乐观锁

2021-03-30 09:45:11

悲观锁乐观锁Optimistic

2022-04-29 11:39:28

MySQL幻读Gap Lock

2010-07-26 15:17:46

SQL Server锁

2011-08-18 13:44:42

Oracle悲观锁乐观锁

2017-05-08 11:46:15

Java多线程

2017-05-31 14:03:07

Java多线程内置锁与显示锁

2021-03-31 10:05:26

偏向锁轻量级锁

2023-07-05 08:18:54

Atomic类乐观锁悲观锁

2023-06-02 08:29:24

https://wwMutex

2019-04-19 09:48:53

乐观锁悲观锁数据库

2019-05-05 10:15:42

悲观锁乐观锁数据安全

2010-07-19 17:57:22

SQL Server锁

2013-06-06 13:10:44

HashMap无锁

2021-03-26 10:40:16

MySQL锁等待死锁

2021-07-03 17:45:57

分布式Redisson MultiLock

2019-01-04 11:18:35

独享锁共享锁非公平锁

2019-11-28 16:00:06

重入锁读写锁乐观锁
点赞
收藏

51CTO技术栈公众号