MySQL支持的锁
从锁粒度上划分
1  | scss复制代码表级锁  | 
从锁操作上划分
从实现方式上划分
使用场景
修改表结构
1  | 复制代码修改数据库表结构会自动加表级锁(元数据锁)  | 
行级锁升级表级锁
1  | 复制代码更新数据未使用索引  | 
更新数据使用索引会使用行级锁
select .... from update使用行级锁
MySQL锁分类
1  | 复制代码分为乐观锁和悲观锁  | 
乐观锁
1  | 复制代码乐观锁是程序通过版本号或时间戳实现  | 
悲观锁
表级锁
1  | 复制代码每次操作锁住整个表  | 
1  | scss复制代码表级锁又分为表锁(MySQL layer层加锁)  | 
表锁
1  | 复制代码需要手动加锁  | 
- read lock
 
1  | 复制代码加读锁后还可以加读锁  | 
- write lock
 
1  | 复制代码加写锁后不能加读锁也不能加写锁  | 
元数据锁
1  | 复制代码自动加锁  | 
意向锁
行级锁
1  | 复制代码每次操作锁住一行数据  | 
共享读锁(S)
1  | csharp复制代码手动加锁  | 
排他写锁(X)
1  | 复制代码自动加锁  | 
- DML(insert、update、delete)
 - select … from udpate
 
整体分类
表级锁使用
表读锁
1  | bash复制代码事务1给mylock表添加读锁  | 
表写锁
1  | bash复制代码事务1给mylock添加表写锁  | 
元数据锁的使用
元数据读锁
1  | 复制代码事务1开启事务  | 
行级锁分类及使用
查询行级锁状态
1  | sql复制代码show status like 'innodb_row_locks'  | 
行级锁的使用
1  | bash复制代码事务1 开始事务  | 
行读锁升级为表锁
未使用索引的行级锁会升级为表锁
1  | ini复制代码事务1开始事务  | 
行写锁
主键索引产生记录锁
1  | bash复制代码事务1开始事务  | 
行锁原理
主键加锁
1  | bash复制代码id为主键索引  | 
唯一键加锁
1  | bash复制代码id为唯一键索引  | 
非唯一键加锁
1  | scss复制代码name是主键  | 
1  | 复制代码有了间隙锁  | 
无索引加锁
1  | bash复制代码name是逐渐  | 
死锁
死锁现象
- 表锁死锁
 - 行级锁死锁
 - 共享锁转换为排他锁
 
表级锁死锁
1  | css复制代码用户A先访问表A 对表A加了锁  | 
解决方案
- 调整程序的逻辑
 
1  | css复制代码把表A和表B当成同一个资源  | 
1  | css复制代码用户A访问完表A和表B之后  | 
- 尽量避免同时锁定2个资源
 
行级锁死锁
产生原因1
1  | rust复制代码在事务中执行了一条不满足for update的操作  | 
解决方案
1  | sql复制代码SQL语句中不要使用太复杂的关联表的查询  | 
产生原因2
1  | 复制代码表中的2个数据id1和id2  | 
解决方案
- 同一个事务中 尽可能做到一次性锁定所有资源
 - 按照id对资源排序 然后按顺序进行处理
 - 采用MVCC机制处理 普通读 不会使用锁
 
共享锁转排他锁
1  | css复制代码事务A查询一条记录 加共享读锁  | 
解决方案
- 避免引发对同一条记录的反复操作
 - 使用乐观锁进行控制
 
本文转载自: 掘金