锁的相关概念不再赘述。
MySQL锁的一些基本知识
MySQL中有三种锁,表锁、行锁、页锁。
MySQL读取数据分为两种,快照读和当前读。
- 快照读通过MVCC实现。
- 快照读在RR和RC隔离级别都有。
- 快照读不需要加锁,当前读会加锁。
锁分类
- 读锁(S锁):同一时间允许多个读操作对同一数据进行操作,不允许写操作。又叫共享锁(shared lock)。
- 写锁(X锁):在当前操作未完成时,阻塞其他任何读写操作。又叫排他锁(exclusive lock)。
- 意向共享锁(IS锁):一个事务获取S锁之前,会先在所在的表加上IS锁。
- 意向排他锁(IX锁):一个事务获取X锁之前,会先在所在的表加上IX锁。
意向锁主要用于处理行锁和表锁之间的矛盾,事务对表进行操作时,能够显示某个事务在此表中的某一行持有了锁,无需逐行检查行锁。
我们如何上锁
表锁
隐式上读锁
select ……;
隐式上写锁
insert ……;
update ……;
delete ……;
显式上读锁
lock table xxx read;
unlock tables;
显式上写锁
lock table xxx write;
unlock tables;
行锁
select不会隐式上读锁。
隐式上写锁
insert ……;
update ……;
delete ……;
显式上读锁,在串行化级别下默认所有select语句都自动加。
begin transaction;
select * from xxx lock in share mode;
commit/rollback;
显式上写锁(事务中)
begin transaction;
select * from xxx lock for update;
commit/rollback;
行锁的三种实现算法
- Record Locks:对索引记录进行加锁,锁是在加在索引上而不是行上的。因为innodb一定存在聚簇索引,所以行锁最终都会落到聚簇索引上。
- Gap Locks:对索引的间隙加锁,防止其他事务插入数据。RC和RU都不存在间隙锁。
- Next-key Locks:可以理解为1+2,相当于把索引和索引前面的间隙都锁住了。RR下是默认的行锁算法。
因为InnoDB行锁是加在索引项的,所以如果通过索引条件检索数据,InnoDB使用行级锁。
否则,会使用Next-Key Locks锁住整张表。RU和RC隔离级别下,不锁表,只锁行。