MySQL(二十)锁(三)乐观锁与悲观锁 显式锁和隐式锁
1 从对待锁的态度划分:乐观锁、悲观锁
- 从对待锁的态度划分,可以将锁划分为乐观锁和悲观锁,可以看出这两种锁是两种对待数据并发的思维方式。
- 乐观锁和悲观锁并不是锁,而是锁的设计思想
1.1 乐观锁
- 乐观锁对数据被其他事务修改持有乐观态度
- 每次不会对数据上锁,而是在更新的时候判断一下其他事务有没有更新这个数据
- 不需要借助数据库本身的锁机制,而是通过程序实现,如
版本号机制
或者cas机制
- 乐观锁适用于多读的场景,能够提高吞吐量
乐观锁的版本号机制
在表中设计一个version
字段,每次在更新的时候更新一下这个字段,如果发生变化则更新失败,重新获取字段进行尝试:
update ... set version = version + 1 where `version` = version;
1.2 悲观锁
- 悲观锁是一种思想,即对数据被其他事务修改持有悲观态度
- 会通过数据库本身的锁机制(比如读写锁、表锁、行锁等)在每次获取数据的时候都进行加锁,其他事务想要获取数据就会堵塞直到它拿到锁。
- 特别对于长事务,悲观锁对于数据库性能开销影响很大
注意点:
-
SQL语句
SELECT ... FOR UPDATE
就是MySQL中的悲观锁,会将扫描过程中的所有行都加锁这是因为MySQL加行锁是加到索引上的,所以如果使用锁没有用到索引,则会进行全表扫描,将全表索引都加上锁
-
当一个事务执行
SELECT ... FOR UPDATE
,另一个事务执行SELECT ...
并不会收到影响,这是因为InnoDB存储引擎采取的是快照读
,不会收到锁的影响