MySQL间隙锁/Next-key演示

MySQL间隙锁/Next-key演示

1. 建表建索引:

CREATE TABLE user( 
id int primary key, 
name varchar(20), 
age int) ENGINE=InnoDB;

CREATE INDEX index_age ON user(age);

INSERT INTO user(id,name,age) VALUES (1,'xiaoming',12);
INSERT INTO user(id,name,age) VALUES (3,'xiaohong',20);
INSERT INTO user(id,name,age) VALUES (5,'laowang',36);

SELECT * FROM user;

在这里插入图片描述

单条索引上加锁,record lock 永远锁的是索引,而非数据本身,如果innodb表中没有索引,那么会自动创建一个隐藏的聚集索引,锁住的就是这个聚集索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。

2. 新建两个session,并取消自动提交事务:

SET AUTOCOMMIT=0;

3. 开始演示:

1)普通索引

#【session_1】查询age=20的记录
mysql> SELECT * FROM user WHERE age=20 FOR UPDATE;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  3 | xiaohong |   20 |
+----+----------+------+
1 row in set (0.00 sec)

#【session-2】(update范围age>=36的操作成功,不会阻塞)
UPDATE user SET name='xiaowang' WHERE age=36;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#(insert范围age>=36的操作成功,不会阻塞,同理age<=12也不会阻塞)
INSERT INTO user(id,name,age) VALUES(7,'laohua',40);
Query OK, 1 row affected (0.00 sec)


INSERT INTO user(name,age) VALUES('xiaoli',30);insert范围20<age<36的操作,会受到阻塞)

通过上面的例子可以看出Gap 锁的作用是在20,36的间隙之间加上了锁。而且并不是锁住了表,可以看出锁住的范围是(12,20]U[20,36)。

2)主键索引/唯一索引

session-1SELECT * FROM user WHERE id = 3 FOR UPDATE;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  3 | xiaohong |   20 |
+----+----------+------+session-2INSERT INTO user(id,name,age) VALUES(4,'xiaoli',30);
Query OK, 1 row affected (0.00 sec)

例子说明的其实就是行锁的原因,我只将id=3的行数据锁住了,用Gap锁的原理来解释的话:因为主键索引和唯一索引的值只有一个,所以满足检索条件的只有一行,故并不会出现幻读,所以并不会加上Gap锁。

3)范围查询

session-1SELECT * FROM user WHERE age > 20 FOR UPDATE;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  5 | laowang |   36 |
+----+---------+------+
1 row in set (0.00 sec)session-2UPDATE user SET name='daming' WHERE age=12;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

INSERT INTO user(id,name,age) VALUES(8,'xiaoli',12);
Query OK, 1 row affected (0.00 sec)

UPDATE user SET name='dahong' WHERE age=20;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

INSERT INTO user(id,name,age) VALUES(7,'xiaoli',20);
#(受到阻塞)

UPDATE user SET name='xiaowang' WHERE age=36;
#(受到阻塞)

可以看到,间隙锁给范围查询加锁时,不允许在边界进行insert操作,而只允许给边界进行update操作。

4)检索条件不存在的情况

  • 等值查询
session-1DELETE FROM user WHERE age =20;
commit;
SELECT * FROM user;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | xiaoming |   12 |
|  5 | laowang  |   36 |
+----+----------+------+
2 rows in set (0.00 sec)

SELECT * FROM user WHERE age = 20 FOR UPDATE;
Empty set (0.00 sec)session-2INSERT INTO user(id,name,age) VALUES(6,'xiaohong',30);
(阻塞)
INSERT INTO user(id,name,age) VALUES(7,'xiaohong',20);
(阻塞)
INSERT INTO user(id,name,age) VALUES(8,'xiaohong',10);
(执行成功)

会锁住[12,20]U[20,36)的区间。

  • 范围查询
session-1SELECT * FROM user WHERE age>40 FOR UPDATE;session-2INSERT INTO user(id,name,age) VALUES(6,'hello',90);
(阻塞)
INSERT INTO user(id,name,age) VALUES(6,'hello',36);
(阻塞)

INSERT INTO user(id,name,age) VALUES(6,'hello',35);
Query OK, 1 row affected (0.00 sec)

会锁住[36,+∞]。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介: 课程总计41课时,从什么是事务讲起,直到分布式事务解决方案,很的0基础基础与提升系列课程。对于难以理解的知识点,全部用画图+实战的方式讲解。 第一部分:彻底明白事务的四个特性:原子性、一致性、隔离性、持久性,用场景和事例来讲解。 第二部分:实战讲数据库事务的6中并发异常:回滚丢失、覆盖丢失、脏读、幻读、不可重复读、MVCC精讲。 第三部分:彻底搞清楚4种事务隔离级别:READ_UNCOMMITTED 读未提交隔离级别、READ_COMMITTED 读已提交隔离级别、REPEATABLE_READ 可重复度隔离级别、SERIALIZABLE 序列化隔离级别 第四部分:彻底搞清楚MySQL的各种:行、表、共享、排它、Next-Key间隙锁、X、S、IS、IX、死、索引与、意向等。 第五部分:彻底搞清楚Spring事务的7种传播级别的原理和使用:PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_NEW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER、PROPAGATION_NESTED分布式事务的理论基础:RPC定理、BASE理论、XA协议都是什么,原理是什么,有什么关联关系 第六部分:分布式事务的5种解决方案原理和优缺点:2PC两阶段提交法、3PC三阶段提交法、TCC事务补偿、异步确保策略、最大努力通知策略 第七部分:阿里巴巴分布式事务框架Seata:历经多年双十一,微服务分布式事务框架,用一个Nacos+Spring Cloud+Seta+MySql的微服务项目,实战讲解阿里的分布式事务技术,深入理解和学习Seata的AT模式、TCC模式、SAGA模式。 课程资料: 课程附带配套2个项目源码72页高清PDF课件一份阿里巴巴seata-1.1.0源码一份阿里巴巴seata-server安装包一份

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值