mysql数据库中存在多种锁。
按照锁模式可以分为乐观锁,悲观锁。
按照范围可以分为行锁和表锁。
按照算法可以分为临间锁、间隙锁、记录锁。
按照属性可以分为共享锁、排它锁。共享锁又称为读锁。排它锁又称为写锁。写锁的优先级比读锁高。
按照状态可以分为意向共享锁和意向排它锁。
行锁和表锁
行锁就是锁住一行或者多行记录。mysql的行锁是基于索引加的。所以行锁是要加在索引响应的行上,即命中索引。行锁锁定的数据量少,并发程度高,但是加锁的开销大。
表锁会锁住整张表,在表锁定期间,仅有一个事务能对该表进行操作。表锁响应的是非索引字段,即全表扫描。
读锁和写锁
select for update和select lock in share mode
在执行select for update时会对
如果只有一个事务对一个表执行select lock in share mode,此后该事务还可以对该表进行update操作,但是如果有多于一个事务对该表进行了select lock in share mode,则任何事务都无法对该表执行update操作。
select for update和select lock in share mode同样遵循行锁和表锁的规则。
建立一张成绩表:
1 | create table scores(id int not null auto_increment, name varchar(20) not null, not null default 0, primary key(id))engine InnoDB charset=utf8; |
表级写锁
在第一个事务中执行:
1 | select * from scores where english = 94 for update; |
在另一个事务中执行:
1 | select * from scores where english = 91 for update; |
这时候第二个事务会被阻塞,因为,第一个事务中的select for update加的表级的写锁,会禁止其他事务对整个表的写操作。所以,这里的事务无法执行,直到超时退出。
行级写锁
如果在第一个事务中执行:
1 | select * from scores where id = 1 for update; |
然后在第二个事务中执行:
1 | select * from scores where id = 2 for update; |
此时,select for update加的是行锁,所以不会阻塞对另一行执行另一个select for update加另一把写锁。
参考文献
[1]深入理解数据库行锁与表锁:https://zhuanlan.zhihu.com/p/52678870
[2]select for update/lock in share mode:https://www.cnblogs.com/liushuiwuqing/p/3966898.html
[3]基本建表语句:https://www.runoob.com/mysql/mysql-create-tables.html
[4]数据库系统原理简单总结:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B3%BB%E7%BB%9F%E5%8E%9F%E7%90%86.md
[5]数据库加锁过程详解:https://www.cnblogs.com/crazylqy/p/7611069.html