MySQL-什么是锁?

228 阅读3分钟

“这是我参与更文挑战的第2天,活动详情查看: 更文挑战

数据库中的数据是共享资源,数据库设计的初衷就已经考虑到了并发访问资源问题。MySQL锁解决并发问题、事务中隔离性的可重复读的问题。

什么是锁呢? 对访问资源进行权限控制并且有序处理。

image.png

锁的级别

1.数据库级别

使用较少不在详细阐述参考官方

dev.mysql.com/doc/refman/…

2.表级别 表级别分为:表锁和元数据锁

例如更新全表会产生表锁。

image.png

例如更新表结构会产生元数据锁

3.行级别

行锁在 InnoDB 中是基于索引实现的,所以一旦某个条件加锁操作没有使用索引,那么该锁就会退化为表锁。

共享锁:当前事物读取数据行,不允许其他事物获取此行排他锁。

排他锁:当前事物更新数据行,不允许其他事物获取任务锁。     

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及及数据集加排他锁(X); 对于普通SELECT语句(读取的是数据快照),InnoDB不会加任何锁;

SELECT语句当然可以手工添加共享锁和排他锁

image.png

image.png

InnoDB行锁实现方式

InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同, 后者是通过在数据中对相应数据行加锁来实现的。 InnoDB这种行锁实现:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁! (建议进行 update Delete 条件使用索引列最好是唯一索引或主键)

行锁三种实现方式: Record Lock:记录锁,单个行记录上的锁。

Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。           间隙锁基于非唯一索引,它锁定一段范围内的索引记录。       比如查询字段区间为1-5,即1-5内的记录行都会被锁住,2、3、4 的数据行的会被阻塞,       但是 1 和 5 两条记录行并不会被锁住。

Next-Key Lock:临键锁,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,可以解决幻读的问题。

InnoDB 中的行锁的实现依赖于索引,一旦某个加锁操作没有使用到索引,那么该锁就会退化为表锁。

记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。(如果查询的列值不存在会产生间隙锁) 间隙锁存在于非唯一索引中,锁定开区间范围内的一段间隔,它是基于临键锁实现的。 临键锁存在于非唯一索引中,该类型的每条记录的索引上都存在这种锁,它是一种特殊的间隙锁,锁定一段左开右闭的索引区间。