@Alpacadh
2022-09-18T17:12:15.000000Z
字数 1621
阅读 221
基本锁类型
mysql
1、共享锁(S Lock)
- 作用:
- 允许事务读一行数据。在select语句后面加上lock in share mode可以显式获取共享锁
- 粒度:
2、排他锁(X Lock)
- 作用:
- 允许事务删除或更新一行数据。update、delete和insert语句会自动给涉及数据集加排他锁,select语句需要在语句后加上for update显式加排他锁
- 粒度:
3、意向锁
3.1 意向共享锁(IS Lock)
- 作用:
- 粒度:
- 表锁(申请意向锁的动作是数据库完成的,也就是说,事务申请行锁的时候,数据库会自动申请表的意向锁,不需要使用方主动申请)
3.2 意向排他锁(IX Lock)
- 作用:
- 粒度:
- 表锁(申请意向锁的动作是数据库完成的,也就是说,事务申请行锁的时候,数据库会自动申请表的意向锁,不需要使用方主动申请)
3.3 作用
- 意向锁的存在是为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存,。
- 例子:事务A修改user表的记录r,会给记录r上一把行级的排他锁(X),同时会给user表上一把意向排他锁(IX),这时事务B要给user表上一个表级的排他锁就会被阻塞。意向锁通过这种方式实现了行锁和表锁共存且满足事务隔离性的要求。
4、上述四个锁的兼容性
IS |
IX |
S |
X |
IS |
兼容 |
兼容 |
兼容 |
IX |
兼容 |
兼容 |
不兼容 |
S |
兼容 |
不兼容 |
兼容 |
X |
不兼容 |
不兼容 |
不兼容 |
5、加锁算法
5.1 记录锁(Record Lock)
作用:
单个行记录上的锁,用来封锁索引记录。
如:假设Test表有主键id和唯一索引列a,已经有了(1,1)这条记录,执行select * from Test where id=1 for update;
会在id=1的索引记录上加锁,以阻止其他事物插入更新、删除id=1这一行。
- record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。
- 所以说当一条sql没有走任何索引时,那么将会在每一条聚合索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。
5.2 间隙锁(Gap Lock)
- 作用:
- 间隙锁属于行锁中的一种,间隙锁是在事务加锁后其锁住的是表记录的某一个区间,当表的相邻ID之间出现空隙则会形成一个区间。锁定一个范围,但不包含记录本身。
- 封锁索引记录中的间隙,确保索引记录的间隙不变。间隙锁是针对事务隔离级别为可重复读(RR)或以上级别而已的,如果隔离级别降级为读提交(RC),间隙锁会自动失效。
- 范围为开区间。
5.3 临键锁(Next-Key Lock)
- 作用:
- 临键锁是记录锁与间隙锁的组合。
- 为了避免幻读,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。
- 范围为左闭右开。
5.4 插入意向锁(Insert Intention Lock)
- 作用:
- 是间隙锁的一种,专门针对insert操作。同一个索引,同一个范围区间插入记录,插入的位置不冲突,不会阻塞彼此,可以提高插入并发。
- 插入意向锁经常和间隙锁引发死锁问题,死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
- 插入不会主动加显示的X Record锁,只有检测到Key冲突的时候才会把隐式锁转为显式锁。
- 隐式锁你可以理解为乐观锁,也就是正常来说不加锁或共享锁,但是遇到冲突则加锁或升级为排它锁。显式锁,那就是真的锁上了。