面试官:请按功能和思想维度总结 Mysql 的各种锁

156 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 5 天,点击查看活动详情

哈喽,大家好,我是二毛。

上篇文章 面试官:按范围维度总结 Mysql 的各种锁 我们按照 范围维度 进行 Mysql 各种锁的总结。

今天我们继续按照 功能维度和思想 来进行总结。

功能维度

排它锁

即写锁,会阻塞所有的读写请求。

分为两种情况,一种是 Mysql 会自动帮我们加上去的,一种是我们显式的手动加上锁。

自动加锁

  • 自动加行级排它锁:更新语句(update/delete/insert),加的是写锁。是 行锁或者间隙锁或next-key-lock,就要看索引命中情况;
  • 自动加表级排它锁:对一张表做结构变更操作的时候,加的是 MDL 写锁;

手动加锁

  • 手动加行级排它锁:select ... for update(select语句一般不会加锁,不过可以显式的指定加锁。)
  • 手动加全局排他锁:flush tables with read lock
  • 手动加表级排他锁:lock tables t_stuent wirte;

共享锁

即读锁。只阻塞写请求。

手动加锁

  • 自动加行级共享锁:select ... lock in share mode
  • 手动加表级共享锁:lock tables t_stuent read;

思想维度

悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。

乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。

或者也可以人为的给数据库表增加一个version字段,每次操作的时候读取并判断 version 字段是否符合业务逻辑即可。

最后

我是二毛,我们下期再见~