数据库 锁
锁是多事务数据库进行并发控制确保一致性,正确性的方式
MySQL锁示意图:
- 对于
UPDATE、DELETE、INSERT
语句,InnoDB会自动给涉及数据集加排他锁(X) - MyISAM在执行查询语句
SELECT
前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT
等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预
——从锁的粒度,我们可以分成两大类:
-
表锁
- 开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
-
行锁
- 开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
——不同的存储引擎支持的锁粒度是不一样的:
- InnoDB行锁和表锁都支持!
- MyISAM只支持表锁!
InnoDB只有通过索引条件检索数据才使用行级锁,否则,InnoDB将使用表锁
- 也就是说,InnoDB的行锁是基于索引的
表锁下又分为两种模式:
- 表读锁(Table Read Lock)
- 表写锁(Table Write Lock)
- 从下图可以清晰看到,在表读锁和表写锁的环境下:读读不阻塞,读写阻塞,写写阻塞
- 读读不阻塞:当前用户在读数据,其他的用户也在读数据,不会加锁
- 读写阻塞:当前用户在读数据,其他的用户不能修改当前用户读的数据,会加锁
- 写写阻塞:当前用户在修改数据,其他的用户不能修改当前用户正在修改的数据,会加锁
- 乐观锁其实是一种思想,正如其名:认为不会锁定冲突的情况下去更新数据,如果发现不对劲,才不更新(回滚)。在数据库中往往添加一个version字段来实现。
- 悲观锁用的就是数据库的行锁,认为数据库会发生并发冲突,直接上来就把数据锁住,其他事务不能修改,直至提交了当前事务