活动地址:CSDN21天学习挑战赛
5. 锁
按锁粒度
5.1 全局锁
全局锁是一个比较重的操作,保证当前数据库所有数据都只能被读取
典型使用场景是做全库的逻辑备份,保证在备份的时候不能操作数据,避免数据不一致
5.2 表级锁
- 表锁
读锁(共享锁):客户端1给表加读锁,有权利读,没权力写,有权利释放锁;该锁不会堵塞客户端2的读,但是会堵塞其他客户端的写
写锁(排他锁):客户端 1给表加写锁,有权利读,有权利写,有权利释放锁;该锁既会堵塞客户端2的读,也会堵塞其他客户端的写
- 元数据锁
简单来说就是,当一个客户端在修改表结构且未提交事务前,其他客户端既不能读也不能写,反之亦然(排他锁)
- 意向锁
意向锁可以解决表锁和行锁的冲突
执行过程:客户端1给某一行数据加行锁,再给整张表加意向锁,客户端2要给这张表加表锁,此时直接去匹配意向锁即可获悉是否能添加表锁成功,不用行检查这张表是否存在行锁
也就是说,如果这行记录是update操作,系统会给这行记录自动加排他行锁(查询操作的话则要自己加共享行锁),同时系统也会给这张表加意向排他锁,那么这时候如果要给这整张表加读锁或者写锁,都是不会成功的
5.3 行级锁
- 行锁
锁住对应的数据行,类型分为排他锁和共享锁
注意:如果在事务提交前对没有索引的行加行锁,行锁将会升级为表锁
原因:InnoDB 行锁是通过索引上的索引项来实现的。意味着:只有通过索引条件检索数据,InnoDB 才会使用行级锁,否则,InnoDB将使用表锁
- 间隙锁&临健锁
首先理解幻读:
注:这个地方设置的冲突字段是id(主键自增)+name(唯一),选取任意一个有唯一约束的字段都会有同样效果
间隙锁如何解决幻读?
行锁只能锁住行,但是新插入记录这个动作,操作的是锁住的行之间的 “间隙”,所以必须靠 行锁+间隙锁 解决幻读问题
SQL 标准中规定的 RR 并不能消除幻读,但是 MySQL 的 RR 可以,靠的就是间隙锁。在 RR 级别下,间隙锁是默认开启的,如上面例子,在开启行锁的同时,间隙锁也被开启了,而在 RC 级别下,间隙锁是关闭的。