[面试题] 乐观锁和悲观锁的实现机制是什么?
📖 知识讲解版 (温故知新)
- 悲观锁:MySQL 内部对写锁的实现。假定冲突一定会发生,因此在操作数据前先加锁(通过
SELECT ... FOR UPDATE等机制)。 - 乐观锁:利用版本号(Version)或时间戳完成,由**用户(业务代码)**实现。假定冲突概率低,只在更新时判断数据是否被修改(CAS思想)。
🎤 面试实战版 (高手逐字稿)
Q:乐观锁和悲观锁的实现机制是什么?
💬 高手逐字稿:
关于乐观锁和悲观锁,我认为它们代表了两种截然不同的并发冲突解决哲学。
首先说悲观锁,它比较“悲观”,认为并发冲突是一定会发生的。所以它的机制是:在操作数据前,先把它锁住。MySQL 数据库内部对于写锁的实现,本质上就是悲观锁。比如我们用 select ... for update,就是直接利用数据库层面的排他锁。
再说乐观锁,它比较“乐观”,认为并发冲突的概率比较低。所以它平时不加锁,而是在真正执行更新操作的时候,去判断一下这期间数据有没有被别人修改过。通常我们在业务层面实现乐观锁,最常用的就是版本号(Version)机制:读取时带出版本号,更新时判断版本号是否一致(类似 update table set ... where id=1 and version=1)。
这时候其实还有一个选型的细节:怎么选?对于写多读少的场景,冲突概率大,用悲观锁能避免频繁重试带来的开销;对于读多写少、竞争不激烈的场景,用乐观锁可以省去数据库加锁释放锁的开销,提高并发度。
其实乐观锁的核心思想就是 CAS(Compare And Swap)。我在以前的项目中,对于高并发的用户账户扣减,一般会优先尝试使用乐观锁加重试机制。
最后更新于: