一、锁的分类
1、范围:全局锁、表级锁、行级锁
2、功能分类:共享锁、排它锁

二、数据库的全局锁
加锁:mysql> flush tables with read lock;
释放锁:mysql> unlock tables;

三、MySQL的表级锁(都是Server层实现的)
1、表级的共享锁:lock table 表名 read; 可以共享读操作,不能做些操作。
2、表级的排他锁:lock table 表名 write; 对表处于一个独享状态。
3、元数据锁:在一个事务中对一个表进行查询操作,不允许其他回话对表结构进行修改,就在表上加元数据锁。
4、自增锁:使用自增字段时,使用自增主键保证主键不冲突有一个自增锁。

四、MySQL的行级锁
要求必须使用InnoDB引擎。
行级锁:
记录锁(Record Locks): 锁定索引中一条记录。
间隙锁(Gap Locks): 要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索引记录后面的值。
临键锁(Next-Key Locks):是索引记录上的记录锁和在索引记录之前的间隙锁的组合(间隙锁+记录锁)。
插入意向锁(Insert Intention Locks):做insert操作时添加的对记录id的锁。
意向锁IX、IS,当数据库中某条记录上有行锁时,需要在表上增加一个标志位,代表当前表中某行记录上有行锁。
1)记录锁
根据主键等值更新时使用记录锁。
共享记录锁:select * from t where id = 1 lock in share mode;
排他记录锁:select * from t where id = 1 for udpate;
2)意向锁
标记当前表中是否有行锁的存在。
行锁:S 意向锁:IS
行锁:X 意向锁:IX
3)间隙锁
在记录和记录之间的范围区间就是间隙,间隙锁就是加区间之上的,防止插入数据。目的就是防止幻读。

行锁加锁规则
1)主键索引
1. 等值查询
(1)命中记录,加记录锁。
(2)未命中记录,加间隙锁。
2. 范围查询
(1)没有命中任何一条记录时,加间隙锁。
(2)命中1条或者多条,包含where条件的临键区间,加临键锁

2)辅助索引
1. 等值查询
(1)命中记录,命中记录的辅助索引项+主键索引项加记录锁,辅助索引项两侧加间隙锁。
(2)未命中记录,加间隙锁
2. 范围查询
(1)没有命中任何一条记录时,加间隙锁。
(2)命中1条或者多条,包含where条件的临键区间加临键锁。命中记录的id索引项加记录锁。

行锁分析
delete from t1 where id = 10;
1 id是主键索引,隔离级别RC, 在id=10的这条记录上加上X锁
2 id是unique辅助索引,隔离级别RC,在辅助索引id=10上的唯一一条记录加X锁,根据辅助索引找到唯一一条主键记录,并加上X锁
3 id是非唯一的辅助索引,隔离级别RC,在辅助索引id=10上多条记录上加X锁,根据辅助索引找到多条主键记录,并加上X锁
4 id不是索引,存储引擎对所有记录加锁,之后由server层对根据id=10进行过滤

5 id是主键索引,隔离级别RR, 在id=10的这条记录上加上X锁
6 id是unique辅助索引,隔离级别RR,在辅助索引id=10上的唯一一条记录加X锁,根据辅助索引找到唯一一条主键记录,并加上X锁
7 id是非唯一的辅助索引,隔离级别RR,在辅助索引id=10上多条记录上加X锁,此外在id=10附近加上间隙锁,根据辅助索引找到多条主键记录,并加上X锁
8 id不是索引,存储引擎对所有记录加锁并对间隙也加锁
9 串行化,delete操作与RR隔离级别相同

如何避免死锁呢?
MySQL默认会主动探知死锁,并回滚某一个影响最小的事务。等另一事务执行完成之后,再重新执行该事务。
如何避免死锁
1、注意程序的逻辑
根本的原因是程序逻辑的顺序,最常见的是交差更新
Transaction 1: 更新表A -> 更新表B
Transaction 2: 更新表B -> 更新表A
Transaction获得两个资源
2、保持事务的轻量
越是轻量的事务,占有越少的锁资源,这样发生死锁的几率就越小
3、提高运行的速度
避免使用子查询,尽量使用主键等等
4、尽量快提交事务,减少持有锁的时间
越早提交事务,锁就越早释放

最新文章

  1. VIM插件攻略
  2. 关于GridView的第一个item图片加载不出来问题
  3. 关于C# DataTable 的一些操作
  4. Lua语言
  5. 那些OVER的封装
  6. C#程序以管理员权限运行【我采用了第二种,比较好用】
  7. Oracle DB 分区特性概述 Overview of Partitions
  8. SQL server 2012 如何取上个月的最后一天
  9. SGU 0438 The Glorious Karlutka River =) 动态流
  10. 一些pyhon的学习资料
  11. HDU 3507 PrintArticle (单调队列优化)
  12. cron 执行php文件
  13. Python C++扩展
  14. 1.6分布式通讯协议-WebService
  15. C# 获取区域和语言值
  16. 从零开始学 Web 之 CSS3(七)多列布局,伸缩布局
  17. PCA和白化练习之处理二维数据
  18. -Java-Runoob-高级教程-实例-数组:09. Java 实例 – 数组扩容
  19. js splice方法
  20. js二分查找树实现

热门文章

  1. 铁威马NAS如何开启二次验证提高系统安全性
  2. vscode问题:由于找不到ffmpag.dll文件,无法继续执行代码
  3. JavaScript:函数:函数的参数
  4. Redis数据结构与对象
  5. Python实验报告(第9章)
  6. ES6 中 Promise对象使用学习
  7. [C++]C++11:Function与Bind
  8. DVWA靶场实战(七)——SQL Injection
  9. Ansible 学习笔记 - 定位主机和组的模式
  10. Stream流中的常用方法_Foreach-Stream流中的常用方法_filter