MySQL 锁详解
- MySQL锁机制
- 概述
- 按使用方式
- 乐观锁
- 概述
- 处理办法
- 悲观锁
- 概述
- 处理办法
- 锁类型
- 按锁粒度区分
- 表级锁
- 概述
- 特点
- 被存储引擎支持的类型
- 行级锁
- 概述
- 特点
- 被存储引擎支持的类型
- 页级锁
- 概述
- 特点
- 被存储引擎支持的类型
MySQL锁机制
概述
按使用方式
乐观锁
概述
假设在极大多数情况下不会形成冲突,只有在数据提交的时候,才会对数据是否产生冲突进行检验。如果数据产生冲突了,则返回错误信息,进行相应的处理。
处理办法
- 使用版本号实现乐观锁
- 使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。并判断当前版本号是不是该数据的最新的版本号。
- 乐观锁不需要数据库底层的支持
悲观锁
概述
悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟java中的synchronized很相似,所以悲观锁需要耗费较多的时间。
处理办法
- 必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式
- 悲观锁是由数据库自己实现了的,要用的时候,我们直接调用数据库的相关语句就可以了
锁类型
- mysql在执行insert、update会自动加锁,mysql对select却不会加锁
- 共享锁
- 其它事务可以读但是不能写
- SQL 写法 - 显式加锁
select * from table where column_name = ‘columnValue’ LOCK IN SHARE MODE
- SQL 写法 - 隐式加锁
select * from table where column_name = ‘columnValue’
- 排它锁
- 只有自己的事务有权限对此数据进行读写吗,其它的事务不可读不可写
- SQL 写法
select * from table where column_name = ‘columnValue’ FOR UPDATE
按锁粒度区分
表级锁
概述
表级锁是 MySQL 中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)
特点
- 开销小,加锁快
- 不会出现死锁
- 一次性同时获取所有需要的锁
- 总是按相同的顺序来获取表锁
- 锁定粒度大,发出锁冲突的概率最高,并发度最低
- 适合于以查询为主,并发用户少,只有少量按索引条件更新数据场景
被存储引擎支持的类型
- MyISAM
- MEMORY
- BDB(页级锁)
- InnoDB(行级锁)
行级锁
概述
锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁分为共享锁和排他锁
特点
- 开销大,加锁慢
- 可能出现死锁
- 单个SQL的事务不会发生死锁
- 多个SQL组成的事务可能发生死锁
- 锁是按顺序逐步获取的
- 锁定粒度最小,发生锁冲突的概率最低,并发度也最高
- 只在存储引擎层实现,MySQL没有实现
- 适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的场景
被存储引擎支持的类型
- InnoDB(行级锁)
页级锁
概述
锁定粒度介于行级锁和表级锁中间的一种锁。采取了折衷的页级锁,一次锁定相邻的一组记录
特点
- 开销和加锁时间界于表锁和行锁之间
- 可能出现死锁
- 单个SQL的事务不会发生死锁
- 多个SQL组成的事务可能发生死锁
- 锁是按顺序逐步获取的
- 锁定粒度界于表锁和行锁之间,并发度一般。
被存储引擎支持的类型
- BDB(页级锁)