1、mysql 的锁
mysql 为并发事务同时对一条记录进行读写时,提出了两种解决方案:
1)使用 mvcc 的方法,实现多事务的并发读写,但是这种读只是“快照读”,一般读的是历史版本数据,还有一种是“当前读”,一般加锁实现“当前读”,或者 insert、update、delete 也是当前读。
2)使用加锁的方法,锁分为共享锁(读锁),排他锁(写锁)
快照读:就是select
- select * from table ….;
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,处理的都是当前的数据,需要加锁。
- select * from table where ? lock in share mode;
- select * from table where ? for update;
- insert;
- update ;
- delete;
mysql 在 RR 级别怎么处理幻读的呢?一般来说,RR 级别通过 mvcc 机制,保证读到低于后面事务的数据。但是 select for update 不会触发 mvcc,它是当前读。如果后面事务插入数据并提交,那么在 RR 级别就会读到插入的数据。所以,mysql 使用 行锁 + gap 锁(简称 next-key 锁)来防止当前读的时候插入。
2、间隙锁
Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作,以此防止幻读的发生。
Innodb自动使用间隙锁的条件:
- (1)必须在Repeatable Read级别下
- (2)检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)
- (3)当查询的索引含有唯一属性(唯一索引,主键索引)时,Innodb存储引擎会对next-key lock进行优化,将其降为record lock,即仅锁住索引本身,而不是范围!若是普通辅助索引,则会使用传统的next-key lock进行范围锁定。
网友评论