MySQL 面试题(三)

143 阅读3分钟
本文已参与「新人创作礼」活动,一起开启掘金创作之路。

MySQL 锁机制

  • 当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制

锁类别上来分 MySQL 有哪些锁

  • 共享锁:又叫读锁
  • 排他锁:数据写入时,对数据加上排他锁;排他锁也称作独占锁,在某一时刻只能被一个线程占有,其他线程必须等待锁被释放之后才可能获取到锁;排他锁只能加一个,与其他排他锁及共享锁都互斥

隔离级别与锁的关系

  • 在读未提交级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突
  • 在读已提交级别下,读操作需要加共享锁,语句执行完以后会释放共享锁
  • 在可重复读级别下,读操作需要加共享锁,在事务提交以后才释放共享锁
  • 在串行化级别下,该级别锁定整个范围的键,并一直持有锁,直到事务完成

按照锁的粒度来分数据库锁有哪些

  • 行级锁

    • 是 MySQL 中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁
    • 加锁粒度最小,开销最大,会出现死锁,锁冲突概率低,并发度最高
  • 表级锁

    • 是MySQL 中锁定粒度最大的一种锁,表示对当前操作的整张表加锁
    • 实现简单,资源消耗较少,MyISAM 与 InnoDB 都支持表级锁
    • 开销小,加锁快,不会出现死锁,锁定粒度大,锁冲突概率最高,并发度最低
  • 页级锁

    • 是 MySQL 中锁定粒度介于行锁和表锁中间的一种锁
    • 会出现死锁,并发度一般,开销和锁定粒度介于表锁和行锁之间

MySQL 中 InnoDB 引擎的行锁如何实现

  • 基于索引完成行锁
  • 例:select * from table_name where id = 23 for update, for upate 可根据查询条件完成行锁锁定,并且id 是有索引键的列
  • 如果 id 不是索引键那么 InnoDB 将完成表锁,并发就没有了

InnoDB 存储引擎的锁算法

  • Record lock:单个行记录上的锁
  • Gap lock:间隙锁,锁定一个范围,但不包括记录本身,会导致幻读产生
  • Next-key lock:上面两种的结合,锁定一个范围,包括记录本身(对行的查询使用)
  • 当查询的索引含有唯一属性时,next-key lock 降级为 record lock

什么时死锁,如何解决

  • 死锁是指多个事务在同一资源上相互占用,并请求锁定对方的资源,导致恶性循环
  • 解决:分布式事务锁或者乐观锁

乐观锁和悲观锁

  • 乐观锁:假设不会发生并发冲突,只是在提交操作时检查是否违反数据完整性;在修改数据的时候把事务锁起来,通过 version 的方式来进行锁定;实现方式一般为版本号机制或 CAS 算法实现

  • 悲观锁:假定会发生并发冲突,在查询完数据的时候就把事务锁起来,知道提交事务;实现方式为数据库中的锁机制 for update

  • 使用场景

    • 乐观锁适用于读多写少的场景,也是一般项目中的大多数场景
    • 多写的场景下可以用悲观锁
  • END -