间隙锁,锁的就是两个值之间的空隙。
间隙锁只有再可重复读级别下才会生效。
Mysql默认级别是可重复读repeatable-read,可重复读存在幻读问题,可以用间隙锁来解决幻读。
例如:
account表数据存在三个间隙:(3,10),(10,20),(20,正无穷)
如果一个事务执行sql:update account set name='aaa' where id>3 and id<18;
那么其他事务将无法在间隙范围(3,20]插入数据。
这个范围包括区间所有数据,和没有插入数据的间隙行和间隙行记录。这个也叫临键锁。
临键锁,简单含义就是行锁和间隙锁的组合,(3,20]就是临键锁。
无索引行锁会升级为表锁
锁主要是加在索引上,如果对非索引字段更新,行锁可能会变表锁。
InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为 表锁。
锁定某一行还可以用lock in share mode(共享锁) 和for update(排它锁),例如:select * from test_innodb_lock where a = 2 for update; 这样其他session只能读这行数据,修改则会被阻塞,直到锁定 行的session提交。
结论
Innodb存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会要更 高一下,但是在整体并发处理能力方面要远远优于MYISAM的表级锁定的。当系统并发量高的时候,Innodb 的整体性能和MYISAM相比就会有比较明显的优势了。
但是,Innodb的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会让Innodb的整体性能表现 不仅不能比MYISAM高,甚至可能会更差。