[MySQL]-行锁、表锁、间隙锁详解学习

MySQL行锁、表锁、间隙锁详解学习

环境准备

创建表

CREATE DATABASE TEST_INNODB;
use TEST_INNODB;
create table TEST_INNODB_LOCK(
    a INT(11) primary key ,
    b VARCHAR(20)
) ENGINE INNODB DEFAULT CHARSET = UTF8;
# 插入数据
insert into TEST_INNODB_LOCK values(1,'a');
insert into TEST_INNODB_LOCK values(2,'b');
insert into TEST_INNODB_LOCK value (3,'c');
insert into TEST_INNODB_LOCK value (4,'d');

结果:

image

创建索引

CREATE INDEX INDEX_LOCK_A ON TEST_INNODB_LOCK(a);
CREATE INDEX INDEX_LOCK_B ON TEST_INNODB_LOCK(b);
# 自动提交变成手动提交
set autocommit = 0;

演示行锁(写&读)

  1. 在一个窗口控制台执行:
update test_innodb_lock set b='a1' where a = 1;

结果:

image

  1. 新的控制台窗口:
    结果:


    image

新开的窗口控制台看到的是旧数据,这是因为 a = 1 的这行记录被 之前的窗口执行的 SQL语句抢到了锁,且没有执行 commit 提交操作。所以后面的窗口控制台看到的是旧数据。这就是 MySQL 隔离级别中的"读已提交"。

4.在的旧的窗口控制台执行

commit;

结果:


image

新的控制台窗口已经读取到最新数据

行锁(写&写)

  1. 一个控制台窗口console执行
update test_innodb_lock set b='a2' where a = 1;
select * from test_innodb_lock;
image

image

这时候并没有 commit 提交,锁是console持有的

  1. console_1 也执行修改
image

console_1 一直处于阻塞状态,因为console还没有执行 commit,还持有锁。console_1 抢不到 a = 1 这行记录的锁,因此一直阻塞等待。

  1. console执行commit 操作


    image

    执行update成功!

表锁

  • 当索引失效的时候,行锁会升级成表锁
  • 索引失效的场景:
    • 对索引自动 or
    • 手动的换型。比如 integer变成就变成了 String
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容