三、读写锁、意向锁、行表锁
1. Mysql锁了解吗
按照锁粒度分类:表锁和行锁
按照读写分类:表级锁和行级锁可以进一步划分为共享锁和排它锁
还有两个表级锁:意向共享锁和意向排它锁
SnailClimb在****
总结的很好很好。。
2. 读写锁和意向锁
排他锁(Exclusive),简写为 X 锁,又称写锁。
共享锁(Shared),简写为 S 锁,又称读锁。
意向共享锁(IS)和意向排他锁(IX):如果事务想要给表中几行数据加上行级共享锁,那么需要先在表级别加上意向共享锁(IS);如果事务想要给表中几行数据加上行级排他锁,那么需要先在表级别加上意向排他锁(IX)(注意:如果是想要加表级S锁或X锁,不需要先加意向锁。)
意向锁的作用:
当向一个表添加表级X锁或者S锁时,如果没有意向锁的话,则需要遍历所有整个表判断是否有不兼容的行锁的存在,以免发生冲突。
如果有了意向锁,只需要判断该意向锁与即将添加的表级锁是否兼容即可,因为意向锁的存在代表了有行级锁的存在或者即将有行级锁的存在,因而无需遍历整个表,即可获取结果。
以下是表级X和S锁和意向锁的兼容性
3. 数据库行锁、表锁(封锁粒度)
MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
- 表锁是mysql中开销最小的策略,它会锁定整张表,用户在对表进行写操作前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
- 特点:锁粒度大,系统开销小,发生锁冲突的概率最高,并发度最低。加锁快,不会出现死锁。表锁是由MySQL Server负责的。
- 行锁可以最大程度的支持并发处理,同时也带来了最大的锁开销,InnoDB存储引擎实现了两种行锁:共享锁和排他锁。行锁在存储引擎层实现。
- 特点: 锁粒度小,系统开销大,发生锁冲突的概率小,并发度最高。加锁慢,会出现死锁。行锁是由InnoDB存储引擎管理的。
4. 什么时候使用表锁?
- 事务更新大表中的大部分数据直接使用表级锁效率更高。如果使用默认的行锁,不仅这个事务执行效率低,而且可能造成其他事务长时间锁等待和锁冲突,这种情况下可以考虑使用表锁来提高该事务的执行速度。
- 事务比较复杂,使用行级索很可能引起死锁导致回滚。这种情况也可以考虑一次性锁定事务涉及的表,从而避免死锁、减少数据库因事务回滚带来的开销。
5. 在InnoDB下 ,使用表锁要注意什么?
- 使用LOCK TALBES虽然可以给InnoDB加表级锁,但必须说明的是,表锁不是由InnoDB存储引擎层管理的,而是由其上一层MySQL Server负责的,仅当autocommit=0、innodb_table_lock=1(默认设置)时,InnoDB层才能知道MySQL加的表锁,MySQL Server才能感知InnoDB加的行锁,这种情况下,InnoDB才能自动识别涉及表级锁的死锁;否则,InnoDB将无法自动检测并处理这种死锁。
- 在用LOCAK TABLES对InnoDB锁时要注意,要将AUTOCOMMIT设为0,否则MySQL不会给表加锁;事务结束前,不要用UNLOCAK TABLES释放表锁,因为UNLOCK TABLES会隐含地提交事务;COMMIT或ROLLBACK产不能释放用LOCAK TABLES加的表级锁,必须用UNLOCK TABLES释放表锁。
6. InnoDB存储引擎的3种行锁算法
Record Lock:锁住一行记录
Gap Lock:间隙锁指的是锁定一个范围内的索引记录,开区间,不包括双端端点,对于键值在条件范围内但不存在的记录,叫做间隙,间隙锁也会对这个间隙加锁。
作用:让其他事务无法在间隙中新增数据,阻止了多个事务记录插入到同一范围内,从而防止了幻读。
Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身,解决了幻读。
- 在可重复读隔离级别下,采用了Next-Key Locking机制避免幻读问题。
- 在读已提交隔离级别下,仅采用Record Lock。
- Next-Key Lock降级为Record Lock仅在查询的列是唯一索引的情况下。