Mysql-锁

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(这些记录并不存在)的“间隙”加锁

你可能感兴趣的:(Mysql-锁)