Lazy loaded imagemysql锁
2023-5-2
| 2025-7-1
字数 3695阅读时长 10 分钟
slug
status
password
icon
AI summary
date
summary
tags
type
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...