1.InnoDB引擎使用了七种类型的锁,他们分别是:
共享锁(S锁)/排它锁(X锁)
意向锁(Intention Locks):表级别的锁
记录锁(Record Locks):记录锁是一种加在索引数据记录上锁,以防止其他事务对于该数据记录进行修改、删除。
间隙锁(Gap Locks):间隙锁是加载某个索引记录区间上的锁,间隙锁防止其他事务在锁定区间上插入新的记录,避免不可重复读。
临键锁(Next-Key Locks):临键锁是记录锁和间隔锁的结合,它既可以锁定索引记录也可以锁定索引记录之间的区间。临键锁主要的目的是解决幻读的问题。
插入意图锁(Insert Intention Locks):插入意向锁是一种间隙锁,当事务视图想向一个区间插入数据时,首先获得插入意向锁。
插入间隙锁规定,如果多个事务向同一区间插入数据时,如果这些数据属于不同的位置(索引位置),那么之间的插入是互不影响的。
自增锁(AUTO-INC Locks):自增锁是一种特殊表锁
2. 加锁语句
select ... from语句:InnoDB引擎采用多版本并发控制(MVCC)的方式实现了非阻塞读,所以对于普通的select读语句,InnoDB并不会加锁【注1】。
select ... from lock in share mode语句:这条语句和普通select语句的区别就是后面加了lock in share mode,通过字面意思我们可以猜到这是一条加锁的读语句,并且锁类型为共享锁(读锁)。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描的唯一索引的唯一行,next-key降级为索引记录锁。
select ... from for update语句:和上面的语句一样,这条语句加的是排他锁(写锁)。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描唯一索引的唯一行,next-key降级为索引记录锁。
update ... where ...语句:。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描唯一索引的唯一行,next-key降级为索引记录锁。【注2】
delete ... where ...语句:。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描唯一索引的唯一行,next-key降级为索引记录锁。
insert语句:InnoDB只会在将要插入的那一行上设置一个排他的索引记录锁。
如果一个查询使用了辅助索引并且在索引记录加上了排他锁,InnoDB会在相对应的聚合索引记录上加锁。
如果你的SQL语句无法使用索引,这样MySQL必须扫描整个表以处理该语句,导致的结果就是表的每一行都会被锁定,并且阻止其他用户对该表的所有插入。
注1:在事务隔离级别为SERIALIZABLE时,普通的select语句也会对语句执行过程中扫描过的索引加上next-key锁。如果语句扫描的是唯一索引,那就将next-key锁降级为索引记录锁了。
注2:当更新语句修改聚合索引(主键)记录时,会对受影响的辅助索引执行隐性的加锁操作。当插入新的辅助索引记录之前执行重复检查扫描时和当插入新的辅助索引记录时,更新操作还对受影响的辅助索引记录添加共享锁。
参考自:https://segmentfault.com/a/1190000013307132 文章写的很好