持续创作,加速成长!这是我参与「掘金日新计划 · 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 字段是否符合业务逻辑即可。
最后
我是二毛,我们下期再见~