InnoDB存储引肇实现了如下两种标准的行级锁
- 共享锁(S Lock),允许事务读一行数据。
- 排他锁(X Lock),允许事务删除或更新一行数据
意向锁(InnoDB的意向锁都是表级别的)
InnoDB存储引擎支持多粒度(granular)锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在。
简单来说意向锁就是加在表上面的粗粒度锁,在获取行锁之前需要先获取意向表锁,减少等待
举例来说,在对表1的记录r加X锁之前,已经有事务对表1进行了IS意向读锁,因为X锁跟IS锁不兼容,所以该事需要等待IS表锁操作的完成
- 意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁
-
意向排他锁(IX Lock),事想要得一张 表中某几行的排他锁
image.png
XS锁冲突例子, for update加的X写锁, lock in share mode加的S读锁
事务A | 事务A | 事务A |
---|---|---|
begin | begin | |
select * from account where id =1 for update; | 事务A对account里面的id为1的数据加X写锁 | |
select * from account where id =1 lock in share mode; | 此时事务B尝试获取id为1的S共享锁 | |
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction | 结果无法获取,锁冲突了 |
InnoDB里面的锁都是针对索引来说的(锁的是索引),如果没有的话行锁就会转为表锁
注:account 表里面有2个字段,分别是主键id,name
事务A | 事务A | 事务A |
---|---|---|
begin | begin | |
select * from account where name = 't' for update; | 事务A对account里面的name为t的数据加X写锁 | |
INSERT INTO account (id , name ) VALUES (5, 'te'); |
此时事务B尝试写入一条数据 | |
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction | 结果无法写入,说明事物A不止锁了 name = 't' 的数据,还锁了整张表 |
网友评论