http://www.cnblogs.com/chenqionghe/p/4845693.html
https://tech.meituan.com/innodb-lock.html
按类型分:
共享锁(IS):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排他锁(IX):允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。
按粒度分:
表级锁
行级锁
MyISAM 不支持事务,表级锁;InnoDB 支持事务,行级锁
InnoDB行锁实现方式
InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的。
InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!
MVCC 多版本并发控制
Innodb的默认隔离级别是:RR 可重复读,就是通过MVCC来实现的。通过MVCC实现了可重复读,并且不需要加锁。
在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。
在实际操作中,存储的并不是时间,而是事务的版本号,每开启一个新事务,事务的版本号就会递增。
Innodb的幻读解决
Innodb的默认隔离级别是:RR 可重复读,但其实是已经解决了RR级别的幻读问题。
行锁防止别的事务修改或删除,
GAP锁防止别的事务新增,
行锁和GAP锁结合形成的的Next-Key锁共同解决了RR级别在写数据时的幻读问题。
InnoDB有三种行锁的算法:
1,Record Lock:单个行记录上的锁。
2,Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。GAP锁的目的,是为了防止同一事务的两次当前读,出现幻读的情况。
3,Next-Key Lock:1+2,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。
Gap 锁(间隙锁):
http://blog.chinaunix.net/uid-20726500-id-5749804.html
假如user表中只有101条记录,其userid 的值分别是1,2,…,100,101,下面的SQL:
SELECT * FROM user WHERE userid > 100 FOR UPDATE
上面是一个范围条件的检索,InnoDB不仅会对符合条件的userid 值为101的记录加锁,也会对userid 大于101(这些记录并不存在)的“间隙”加锁