mysql锁
锁分类
读锁(共享锁)
写锁(排他锁)
按照锁的粒度划分
全局锁 锁整个数据库,一般用于数据迁移、数据备份
表锁 一般用于alter table、drop table、trunck table、lock table
行所 select...for udpate、insert、update、delete
间隙锁 select ... from student where id >= 10 and id <= 20 for update; 会锁住(10~20的区间)包括10和20,只有可重复读级别才会生效
select ... from student where id = 12 for update; 也会锁住(10~20的区间)不包括10和20,只有可重复读级别才会生效
临键锁 select ... from student where age = 10 for update; 会锁住(10,20],左开右闭。age不能是唯一索引,临键锁只能作用在非唯一索引上

意向锁
意向共享锁(表锁)
意向排他锁(表锁)
意向锁的作用
一个事务在数据上加表锁之前,直接检查意向锁即可确定是否可以加表锁
乐观锁
适用场景:读多写少,冲突少的场景。合适使用乐观锁可以提高吞吐量
悲观锁
适用场景:事务并发冲突多的场景,避免使用乐观锁时由于冲突多导致的大量回滚
不适合使用乐观锁的场景
如果事务并发修改同一行的概率很高,就不适合使用乐观锁
如果需要长时间锁定某些数据,也不适合使用乐观锁
因为这种场景很可能造成大量事务的冲突或回滚,此时悲观锁是很好的选择
乐观锁的劣势:
需要我们来管理版本号
需要额外的代码控制
事务冲突多的时候,开销比较大
悲观锁的劣势:
并发度降低
死锁
锁超时
何时加读锁,何时加写锁?
select .... for update 会添加排他锁(对选定的行)
select .... in share mode 会添加共享锁(对选定的行)
insert 会添加排他锁(对选定的行)
update 会添加排他锁(对选定的行)
delete 会添加排他锁(对选定的行)
行锁的缺点
死锁
两个以上的事务在执行过程中因为争夺资源互相等待,没有外力作用的情况下,会一直等待下去
锁升级
如果需要锁定很多行,但是锁定这些行开销很大,甚至大过表锁的开销,此时会升级为表锁
锁等待
如果一个事务锁定了某行,其他事务就必须等待,如果等待的事务多了,会造成额外的开销,甚至出现性能瓶颈
资源消耗
浙公网安备 33010602011771号