目录
问题分析
要回答好这个问题,需要先了解MySQL中为什么要引入锁。
在多个事物并行对同一个数据进行修改的时候,会产生事物的竞争造成脏读、幻读、不可重复读等问题。
所谓MySQL为了避免这类问题的出现,引入了事物隔离级别,其实本质上来说,最终解决的方式无非就是LBCC和MVCC两种。而锁是解决事物竞争问题的底层实现方式。
通常来说,加锁会影响性能,所以一般情况下都会考虑到性能和安全性的平衡,而MySQL,也根据不同的作用范围,提供了不同的锁的实现方式。
而这个问题,就是考察候选人对锁范围的理解,下面来看下这个问题的回答思路。
问题解答
MySQL的Update操作既可以锁行,也可以锁表,具体使用哪种锁类型,取决于执行的Update语句的条件、事务隔离级别等因素。
1、如果update语句中的where条件包含了索引列,并且只更新一条数据,那这个时候就加行锁。如果where条件中不包含索引列,这个时候会加表锁。
2、另外,根据查询范围不同,MySQL也会选择不同粒度的锁来避免幻读问题。
比如针对主键索引的for update操作:
SELECT * FROM t WHERE id = 10 FOR UPDATE;
MySQL会增加Next-Key Lock 来锁定id=10索引所在的区间
3、另外,针对于索引区间的查询或者修改
SELECT * FROM user WHERE id BETWEEN 1 AND 100 FOR UPDATE;
MySQL会自动对索引间隙加锁,来解决幻读问题。