数据库锁机制

本文深入探讨了InnoDB数据库的锁机制,包括行锁、表锁、页锁及其类型,如记录锁、间隙锁、临键锁。分析了InnoDB如何在不同场景下加锁,如主键索引与二级索引查询时的锁行为,并提到了意向锁的作用,旨在理解锁对并发性能的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

锁,很少人为操作,一般有: for update

====一堆名词,一个个分析吧============================

Innodb聚簇索引是给索引加锁

 

  1. 按照锁的粒度划分:行锁、表锁、页锁,记录锁,间隙锁,临键锁、

表锁:粒度大,简单,容易冲突,不会出现死锁,MyISAM和InnoDB都支持。DDL语句会自动加表锁,AlterTable 这种。也可以手动lock unlock

行锁:最细粒度,锁一行或者多行数据。粒度小,麻烦(一行一行加锁),不容易冲突,会出现死锁。

Innodb是聚簇索引,二级索引查询时需要回表,那就需要两把锁

下面以两条 SQL 的执行为例,讲解一下 InnoDB 对于单行数据的加锁原理。

update user set age = 10 where id = 49;//第一条 SQL 使用主键索引来查询,则只需要在 id = 49 这个主键索引上加上写锁; update user set age = 10 where name = 'Tom';//第二条 SQL 则使用二级索引来查询,则首先在 name = Tom 这个索引上加写锁,然后由于使用 InnoDB 二级索引还需再次根据主键索引查询,所以还需要在 id = 49 这个主键索引上加写锁,

也就是说使用主键索引需要加一把锁,使用二级索引需要在二级索引和主键索引上各加一把锁。

页锁:介于行和表锁之间,也会死锁

记录锁:属于行锁,但是只锁一行,必须是唯一索引。 解决脏读重复读

当 SQL 语句无法使用索引时,会进行全表扫描,这个时候 MySQL 会给整张表的所有数据行加记录锁,再由 MySQL Server 层进行过滤。但是,在 MySQL Server 层进行过滤的时候,如果发现不满足 WHERE 条件,会释放对应记录的锁。这样做,保证了最后只会持有满足条件记录上的锁,但是每条记录的加锁操作还是不能省略的。

所以更新操作必须要根据索引进行操作,没有索引时,不仅会消耗大量的锁资源,增加数据库的开销,还会极大的降低了数据库的并发性能。

selct * from user where id=1 for update 命中一条数据,自动触发记录锁

间隙锁:属于行锁,锁区间的,左开右闭

selct * from user where id>5 and id

其他事务,无法操作5-9区间的数据,被间隙锁锁住了

问题:selct * from user where id>15 for update 会怎么加锁,updaete 14的时候会成功吗,不会。

正常人理解,

其实:因为间隙锁是根据现有数据划分的锁,11到无穷大,大于11都是需要锁的哦。

临建锁(Next-Key-Lock):属于行锁,Innodb默认的,是间隙锁和记录锁的结合

selct * from user where id>5 and id

  1. 按照锁的属性:共享锁、排它锁(悲观锁的一种实现)

Innodb会自动在delete/update/insert加上锁,select* from a for update就是排他锁

共享锁(属于行锁):读锁,让别人只能读,不能改

排他锁(属于行锁):写锁,不能与其他锁共存

  1. 锁的状态分类:意向共享锁,意向排他锁

意向锁属于(表锁)

意向锁是记录行锁和表锁的。比如像alert table的时候,需要看看表里面有表锁和行锁没,就用意向锁来记录。

监控意向锁就可以知道,表中到底有没有锁了

由于表锁和行锁虽然锁定范围不同,但是会相互冲突。所以当你要加表锁时,势必要先遍历该表的所有记录,判断是否加有排他锁。这种遍历检查的方式显然是一种低效的方式,MySQL 引入了意向锁,来检测表锁和行锁的冲突。

意向锁也是表级锁,也可分为读意向锁(IS 锁)和写意向锁(IX 锁)。当事务要在记录上加上读锁或写锁时,要首先在表上加上意向锁。这样判断表中是否有记录加锁就很简单了,只要看下表上是否有意向锁就行了。

意向锁之间是不会产生冲突的,也不和 AUTO_INC 表锁冲突,它只会阻塞表级读锁或表级写锁,另外,意向锁也不会和行锁冲突,行锁只会和行锁冲突。

意向锁是InnoDB自动加的,不需要用户干预。**对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);

对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值