Lazy loaded imagemysql锁
2023-5-2
| 2025-7-1
字数 3695阅读时长 10 分钟
slug
mysql锁
status
Published
password
icon
AI summary
date
May 2, 2023
summary
mysql锁
tags
开发
type
Post
category
技术分享

1、mysql锁

1.1、锁粒度

表级锁、行级锁、页级锁

表级锁

行级锁

页级锁

总结

1.2、共享锁、排它锁

InnoDB 实现了标准的行级锁,包括两种:共享锁(简称 s 锁)、排它锁(简称 x 锁)。
对于共享锁而言,对当前行加共享锁,不会阻塞其他事务对同一行的读请求,但会阻塞对同一行的写请求。只有当读锁释放后,才会执行其它事物的写操作。
对于排它锁而言,会阻塞其他事务对同一行的读和写操作,只有当写锁释放后,才会执行其它事务的读写操作。
notion image
简而言之,就是
读锁会阻塞写(X),但是不会堵塞读(S)。而写锁则会把读(S)和写(X)都堵塞
对于InnoDB 在RR(MySQL默认隔离级别) 而言,对于 update、delete 和 insert 语句, 会自动给涉及数据集加排它锁(X);
对于普通 select 语句,innodb 不会加任何锁。如果想在select操作的时候加上 S锁 或者 X锁,需要我们手动加锁。
用 select… in share mode 获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行 update 或者 delete 操作。
但是如果当前事务也需要对该记录进行更新操作,则有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用 select… for update 方式获得排他锁。

1.3、加锁模式

记录锁(Record Locks)

  • 同时查询语句必须为精准匹配(=),不能为 >、<、like等,否则也会退化成临键锁。
    • 其他实现
      在通过 主键索引 与 唯一索引 对数据行进行 UPDATE 操作时,也会对该行数据加记录锁:
      ==记录锁是锁住记录,锁住索引记录,而不是真正的数据记录.==
      ==如果要锁的列没有索引,进行全表记录加锁==
      记录锁也是排它(X)锁,所以会阻塞其他事务对其插入、更新、删除。
      notion image

间隙锁(Gap Locks)

临键锁(Next-Key Locks)

notion image
  • 记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。
  • 间隙锁存在于非唯一索引中,锁定开区间范围内的一段间隔,它是基于临键锁实现的。
  • 临键锁存在于非唯一索引中,该类型的每条记录的索引上都存在这种锁,它是一种特殊的间隙锁,锁定一段左开右闭的索引区间。

意向锁

  • 意向锁是一种 不与行级锁冲突的表级锁,这一点非常重要。
  • 意向锁是 InnoDB 自动加的, 是由数据引擎自己维护的,用户无法手动操作意向锁,
==在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。==
  • 意向锁是在 InnoDB 下存在的内部锁,对于MyISAM 而言 没有意向锁之说。

插入意向锁

  • 插入意向锁之间互不排斥,所以即使多个事务在同一区间插入多条记录,只要记录本身(主键、唯一索引)不冲突,那么事务之间就不会出现冲突等待。
    • 虽然插入意向锁中含有意向锁三个字,但是它并不属于意向锁而属于间隙锁,因为意向锁是表锁而插入意向锁是行锁。
      现在我们可以回答开头的问题了:
      1、 使用插入意向锁与记录锁。
      2、事务 A 不会阻塞事务 B。
  • age 区间在(15,20] 的间隙锁。
    • 最终,事务 A 插入了该行数据,并锁住了(10,20] 这个区间。
      随后事务 B 试图插入一行数据:
      因为 16 位于(15,20] 区间内,而该区间内又存在一把间隙锁,所以事务 B 别说想申请自己的间隙锁了,它甚至不能获取该行的记录锁,
      自然只能乖乖的等待 事务 A结束,才能执行插入操作。
      很明显,这样做事务之间将会频发陷入阻塞等待,插入的并发性非常之差。
      这时如果我们再去回想我们刚刚讲过的插入意向锁,就不难发现它是如何优雅的解决了并发插入的问题。
  • 插入意向锁是一种特殊的间隙锁。
  • 插入意向锁在锁定区间相同但记录行本身不冲突的情况下互不排斥。
 
  • 开发
  • openwrtPowerDesigner
    Loading...