Innodb间隙锁实战

锁概念

InnoDB存储引擎包含了三种行锁的算法,分别如下所示:

  • Record Lock:行锁,针对的是单行记录;
  • Gap Lock:间隙锁,锁定的是一个范围,但是不包含记录本身;
  • Next-Key Lock:其实就是行锁+间隙锁,包含了记录本身和范围;

为什么需要间隙锁

数据库一般都有四种隔离级别,其中最常用的就是:已提交读(Read committed)和可重复读(Repeatable read);在已提交读隔离级别下会出现不可重复读的现象,而在可重复读隔离级别下会出现幻读(Phantom Read)的现象;

幻读:同一事务下,连续执行两次同样的SQL可能会导致不同的结果;

Innodb引擎在可重复读隔离级别下并不会出现幻读的现象,这主要是因为Innodb提供了多版本并发控制MVCC间隙锁;常见的快照读其实就是使用的MVCC,而当前读就使用了间隙锁;

以下实例有两点说明:

  • Innodb的可重复读隔离级别下,对当前读使用了间隙锁来解决幻读的问题,所以下面的实例都是基于默认隔离级别RR;
  • Innodb的锁机制都依赖索引,所以下面的实例围绕索引来展开;

实战

无索引的情况

首先创建一个无索引的表,并初始化数据:

mysql> create table t1(a int);
mysql> insert into t1 values(1),(3),(5);

启动事务1,执行当前读:

mysql> begin;
mysql> select * from t1 where a=3 for update;

以上事务没有提交,再启动事务2,以下语句都被阻塞:

mysql> select * from t1 where a=3 for update;
mysql> insert into t1 values(1);
mysql> insert into t1 values(2);
mysql> insert into t1 values(5);
mysql> insert into t1 values(7);

但是这时候去执行快照读还是可以的:

mysql> select * from t1 where a=3;

可以发现在没有索引的情况下,除了快照读什么都干不了,感觉像是表被锁住了,表锁分为读和写锁,在写锁的情况下快照读同样被锁住,而在读锁的情况下可以使用快照读,类似上面无索引的情况;

mysql> lock table t1 read;  ## 读锁
mysql> lock table t1 write;  ## 写锁
mysql> unlock tables;  ## 解锁

那是不是无索引的情况下就使用了表锁那,可以通过如下命令进行查看,首先看一下在表锁的情况下执行插入操作:

mysql> SHOW PROCESSLIST;
+-----+------+-----------------+------+---------+------+------------------------------+--------------------------+
| Id  | User | Host            | db   | Command | Time | State                        | Info                     |
+-----+------+-----------------+------+---------+------+------------------------------+--------------------------+
|  75 | ODBC | localhost:65316 | test | Query   |   98 | Waiting for table level lock | insert into t1 values(7) |
+
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值