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查询一条记录 加共享读锁 |
解决方案
- 避免引发对同一条记录的反复操作
- 使用乐观锁进行控制
本文转载自: 掘金