MySQL 高级 --- Innodb 的行锁 , 到底锁的是什么?( 面试 )

哪些引擎支持数据库事务?

 

mysql 锁级别

1. 表级锁 : 开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高 , 并发度最低。

2. 行级锁 : 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低 , 并发度也最高。

3. 页面锁 : 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

sql 测试代码 

CREATE TABLE `t_customer` (
  `id` INT(20) NOT NULL AUTO_INCREMENT,
  `cname` VARCHAR(50) NOT NULL,
  `age` INT(10) NOT NULL,
  `phone` VARCHAR(20) NOT NULL,
  `sex` TINYINT(4) NOT NULL,
  `birth` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
 
 
INSERT INTO t_customer(cname,age,phone,sex,birth) VALUES('z3',22,'13811112222',1,NOW());
INSERT INTO t_customer(cname,age,phone,sex,birth) VALUES('z4',24,'13811112223',0,NOW());
INSERT INTO t_customer(cname,age,phone,sex,birth) VALUES('z5',25,'13811112224',1,NOW());
 
SELECT * FROM t_customer;
 
create index idx_cname on  t_customer(cname);
 
 

案例 1

1. 开启事务 , 更改表中的电话为 xxx 的 age 字段 , 注意此时 phone 字段还没有创建索引 , 也没有回滚事务或者提交事务 ( 无 rollback 和 commit 意为 : 没有释放锁 )

2. phone 字段上面没有创建索引 , 开启事务 , 无提交 , 行锁变表锁

3. 当其他客户端也进行表数据的更改时 , 虽然更改的是其他的数据行 , 但是由于整个表被锁了 , 也会导致无法成功修改 , 处于一直执行的状态 , 转圈圈 , 直到前一个客户端提交事务 , 释放锁 , 才可成功的执行

原因 :

1. 索引没命中 ( 某字段 , 我没有创建它的索引 , 但是呢 , 我却用到了此字段作为条件进行查询等操作 ) ,变成表锁 , 没有使用到索引

2. 索引命中了就是行锁 , 我即使锁的是A记录 , 你操作的是B记录 , 因为是锁的是行 , 之间并不会相互影响

 

案例 2

索引命中,行锁 ( 创建了索引 , 并且使用到了索引就是命中索引 , 命中索引 , 开启事务, 锁的就是行 )

id 主键索引 + 聚簇索引 + 一级索引

辅助索引的意思就是 : 非主键索引外的索引

总结

1. InnoDB 的行锁,是通过锁住索引来实现的,如果加锁查询的时候没有使用到索引,会将整个聚簇索引都锁住,相当于锁住了整张表。

2. 就是说 : 命中索引锁行没有命中锁表 ( 问题会扩大化,小心 )

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值