- 从锁的粒度上分MySQL 支持的锁的表级锁、行级锁(InnoDB)、页级锁(BDB)
- 从锁的 *** 作上分为读锁和写锁
- 从实现方式上分乐观锁和悲观锁
- 修改数据库表结构会自动加表级锁 - 元数据锁
- 更新数据未使用索引,行锁会上升未表级锁
- 更新数据使用索引会使用行级锁
- select … for update 会使用行级锁
MySQL Server 层实现;
每次 *** 作锁住整张表.锁定粒度大,发生锁冲突的概率最高,并发度最低,应用在My ISAM、InnoDB、 BDB等存储引擎中。
MySQL的表级锁有两种:
一种是表锁。
表锁有两种表现形式:
表共享读锁(Table Read Lock)
表独占写锁(Table Write Lock)
一种是元数据锁(meta data lock, MDL) 。
表锁 - 意向锁MDL (metaDataLock)
元数据:表结构
在MySQL5.5版本中引入了MDL,
当对一个表做增删改查 *** 作的时候,加MDL读锁;
当要对表做结构变更 *** 作的时候,加MDL写锁。
意向锁(升级机制)
当一个事务带着表锁去访问一个被加了行锁的资源,那么此时,这个行锁就会升级成意向锁,将表锁住。
# 事务A - 升级表锁 select * from table where id = 3 for update # 事务B - 锁表 select * from table where id <> 3 for update表锁 - 自增锁
行级锁事务插入自增类型的列时,获取自增锁
如果一个事务正在往表里插入自增记录,其他事务都必须等待
行级锁:每次 *** 作锁住一行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。
应用在InnoDB存储引擎中。
RecordLock锁(记录锁):锁定单个行记录的锁。RC、RR隔离级别都支持。
键值在条件范围内
记录存在
存在 id= 1的记录 select * from table id = 1 for update
GapL ock锁(间隙锁):锁定索引记录间隙,确保索引记录的间隙不变。RR隔离级别支持。
对于键值不存在条件范围内,叫做“间隙(GAP)”,引擎就会对这个间隙加锁,这种机制就是Gap 机制
只存在 id = 2 和 id = 9 的记录 select * from table where id = 4 for update
Next-key Lock锁(临键锁):行锁和间隙锁组合,同时锁住数据,并且锁住数据前面的Gap。 RR隔离级别支持。
在键值范围条件内,同时键值没有命中
只存在 id = 9 的记录 select * from table where id > 4 for update死锁
共享锁 和 排他锁加锁是实现数据库并发控制的一个非常重要的技术.当两个事务的锁发生冲突,互相等待对方的锁释放,不能继续执行事务逻辑,就会出现死锁,严重影响应用的正常执行.
死锁的现象主要有:表锁死锁、行级锁死锁、共享锁转换为排他锁.
行锁和表锁其实是粒度的概念 ,共享锁和排它锁是他们的具体实现
- 共享锁(S)
允许一个事务去读一 行,阻止其他事物去获取该行的排它锁。
一般理解:能读,不能写 - 排它锁(X) :写锁
允许持有排它锁的事务读写数据,阻止其他事务获取该资源的共享锁和排它锁。
不能获取任何锁,不代表不能读(MVCC 可以读取数据的历史版本) - 注意点
某个事务获取数据的排它锁,其他事务不能获取该数据的任何锁,并不代表其他事务不能无锁读取该数据。
# 无锁 select ... from ... # 共享锁 select ... lock in share mode # 排他锁 update ... delete ... insert ... select ... from ... for update
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)