当前位置:   article > 正文

mysql 表锁和行锁_mysql 查行锁和表锁

mysql 查行锁和表锁

一、表锁

表读锁 lock table read; 一个session设置读锁,当前session更新和插入都会报错,另一个session只能读,写会阻塞。

表写锁 lock table write; 一个session设置写锁,当前session可以增删改查都可以,另一个session不能读写都会阻塞,直到锁被释放。  unlock tables;

二、共享锁

行共享锁: select * from 表名 where id = 1 lock in share mode; 当一个session设置共享锁,另一个session也可以设置共享锁成功。查询操作不影响,当第一个session进行更新操作会阻塞,第二个session进行更新操作时会因为发生死锁而退出,此时第一个session设置成功。第一个session可以读写,第二个session也可以读,但是写操作直到第一个session commit之后才能进行操作。

三、排他锁

行排他锁  select * from 表名 where id = 1 for update; 当一个session设置排他锁,另一个session在设置锁时会阻塞,第一个session可以读写,第二个session也可以读,但是写操作直到第一个session commit之后才能进行操作。

注:1、mysql 会把 update insert delete 操作 隐式添加for update;

       2、mysql 加行锁时,如果改sql没有用到索引,那它会将转换成表锁。行锁并不是争对记录,而是对索引。

mysql 记录锁 间隙锁 临键锁

记录锁:record lock,即锁住一条记录
间隙锁:gap lock,即锁定一个区间,左开右开
临键锁(next-key lock):记录锁+间隙锁锁定的区间,左开右闭

四、数据准备

  1. CREATE TABLE `book` (
  2. `id` int(11) NOT NULL,
  3. `isbn` varchar(25) DEFAULT NULL,
  4. `author` varchar(25) DEFAULT NULL,
  5. `score` decimal(10,2) DEFAULT NULL,
  6. PRIMARY KEY (`id`),
  7. UNIQUE KEY `uk_isbn_key` (`isbn`),
  8. KEY `idx_author_key` (`author`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  10. -- ----------------------------
  11. -- Records of book
  12. -- ----------------------------
  13. INSERT INTO `book` VALUES ('10', 'N0001', 'Bob', '3.40');
  14. INSERT INTO `book` VALUES ('18', 'N0002', 'Alice', '7.70');
  15. INSERT INTO `book` VALUES ('25', 'N0003', 'Jim', '5.00');
  16. INSERT INTO `book` VALUES ('30', 'N0004', 'Eric', '9.10');
  17. INSERT INTO `book` VALUES ('41', 'N0005', 'Tom', '2.20');
  18. INSERT INTO `book` VALUES ('49', 'N0008', 'Tom', '8.30');

记录锁 select * from bookwhere id=1 for update;//锁住一行,通过主键索引和唯一索引实现。

1、主键命中索引(记录锁)

1.1 查询命中主键索引 

  1. 事务1
  2. begin;
  3. select * from book where id = 18 for update;
  4. 事务2
  5. select、update、delte 锁住区间 等于 id = 18 和 id 在 > (负无穷大,18] 区间阻塞,id 在 < [10,正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  6. -------------------------------------------------
  7. insert 阻塞区间 id=18

2、主键未命中索引

2.1 查询未命中索引

  1. 事务一
  2. begin;
  3. select * from book where id = 12 for update;
  4. 事务二、
  5. selectupdate、delte 锁住区间 等于 和 >< 无阻塞
  6. -----------------------------------------------------
  7. insert 锁住区间 (10,18)

 3、二级命中唯一索引(记录锁)

 3.1 二级唯一索引,查询命中 

  1. 事务一、
  2. begin;
  3. select * from book where isbn = 'N0003' for update;
  4. 事务二、
  5. select、update、delte 锁住区间 isbn 等于 'N0003' 在 > (负无穷大,'N0004'] 区间阻塞,isbn 在 < ['N0002',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  6. -----------------------------------------------------
  7. insert 锁住区间 ['N0003','N0003']

4、二级未命中唯一索引

4.1 查询未命中(中间位)

  1. 事务一
  2. begin;
  3. select * from book where isbn = 'N0006' for update;
  4. 事务二、
  5. select、update、delte 锁住区间 等于 和 > 和 < 无阻塞
  6. --------------------------------------------
  7. insert 锁住区间 ['N0005','N0008']

4.1.2   查询未命中(边位)

  1. 事务一
  2. begin;
  3. select * from book where isbn = 'N00005' for update;
  4. 事务二
  5. select、update、delte 锁住区间 等于 和 > 和 < 无阻塞
  6. --------------------------------------------
  7. insert 锁住区间 [负无穷大,'N0001')

5、命中二级索引

5.1 查询命中

5.1.1 中间位

  1. 事务一、
  2. select * from book where Author = 'Jim' for update;
  3. 事务二、
  4. select、update、delte 锁住区间 Author 等于 'Jim' 在 > (负无穷大,'Jim'] 区间阻塞,Author 在 < ['Eric',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  5. -----------------------------------------------------
  6. insert 锁住区间 ['Eric','Tom']
  7. insert into book VALUE(42,'N00049','Tom',1.1);
  8. 当author = 'Eric'时,会阻塞id>30记录,id < 30 不会阻塞
  9. 当author = 'Tom'时,会阻塞id<41记录,id > 41 不会阻塞

5.1.2  边位

  1. 事务一
  2. begin;
  3. select * from book where Author = 'Alice' for update;
  4. 事务二、
  5. select * from book where Author = 'Eric' for update;-- 阻塞
  6. select * from book where Author = 'Eric1' for update;-- 不阻塞
  7. UPDATE book SET score = 9.2 WHERE Author = 'Eric'; -- 阻塞
  8. UPDATE book SET score = 9.2 WHERE Author = 'Eric1'; -- 不阻塞
  9. delete from book where Author = 'Eric'; -- 阻塞
  10. delete from book where Author = 'C1'; -- 不阻塞
  11. insert into book VALUE(11,'N0009','Bob',1.1);-- 阻塞 锁住区间(Bob,Jim) 再按照id区间比较(10,25)
  12. insert into book VALUE(11,'N0009','Jam',1.1);-- 阻塞 锁住区间(Bob,Jim) 再按照id区间比较(10,25)
  13. insert into book VALUE(42,'N0009','A1',1.1);-- 不阻塞
  14. insert into book VALUE(11,'N0009','A1',1.1);-- 不阻塞

  

5.2 更新命中和查询命中 同理

6、未命中二级索引(和主键索引也关系)

6.1 查询未命中

6.1.1 中间位

  1. 事务一、
  2. begin;
  3. select * from book where Author = 'C1' for update;
  4. 事务二、
  5. select * from book where Author = 'C1' for update;-- 不阻塞
  6. select * from book where Author = 'D1' for update;-- 不阻塞
  7. UPDATE book SET score = 9.2 WHERE Author = 'C1'; -- 不阻塞
  8. UPDATE book SET score = 9.2 WHERE Author = 'Bob'; -- 不阻塞
  9. delete from book where Author = 'C1'; -- 不阻塞
  10. delete from book where Author = 'Eric'; -- 不阻塞
  11. insert into book VALUE(11,'N0009','Bob',1.1);-- 阻塞 锁住区间(Bob,Jim),再按照id区间比较,见下图
  12. insert into book VALUE(9,'N0009','Bob',1.1);-- 不阻塞 ????
  13. insert into book VALUE(11,'N0009','Eric1',1.1);-- 阻塞 锁住区间(Bob,Jim),再按照id区间比较,见下图
  14. insert into book VALUE(11,'N0009','F1',1.1);-- 不阻塞

从上文两条sql语句中

insert into book VALUE(11,'N0009','Bob',1.1);

insert into book VALUE(9,'N0009','Bob',1.1); 

6.1.2 边位

  1. 事务一
  2. begin;
  3. select * from book where Author = 'U1' for update;
  4. 事务二、
  5. select * from book where Author = 'U1' for update;-- 不阻塞
  6. select * from book where Author = 'V1' for update;-- 不阻塞
  7. UPDATE book SET score = 9.2 WHERE Author = 'U1'; -- 不阻塞
  8. UPDATE book SET score = 9.2 WHERE Author = 'Bob'; -- 不阻塞
  9. delete from book where Author = 'U1'; -- 不阻塞
  10. delete from book where Author = 'Tom1'; -- 不阻塞
  11. insert into book VALUE(11,'N0009','Tom1',1.1);-- 阻塞 锁住区间(Tom,无穷大)
  12. insert into book VALUE(11,'N0009','V1',1.1);-- 阻塞 锁住区间(Tom,无穷大)
  13. insert into book VALUE(11,'N0009','Tom',1.1);-- 不阻塞

7、主键索引 范围

  1. 事务一、
  2. begin;
  3. select * from book where id > 18 for update;
  4. 事务二、
  5. select * from book where id > 18 for update; -- 阻塞
  6. select * from book where id < 26 for update; -- 阻塞
  7. select * from book where id < 19 for update; -- 阻塞
  8. select * from book where id = 26 for update; -- 不阻塞
  9. select * from book where id = 25 for update; -- 阻塞
  10. select * from book where id = 50 for update; -- 不阻塞
  11. select * from book where id > 49 for update; -- 不阻塞
  12. select * from book where id = 10 for update; -- 不阻塞
  13. UPDATE book SET score = 9.2 WHERE id = 26; -- (update和select同理)
  14. select、update、delte 锁住区间 等于25304149 和 id 在 > (负无穷大,48] 区间阻塞,id 在 < [19,正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  15. -----------------------------------------------------------------------------------------
  16. insert into book VALUE(26,'N00051','Jim',1.1);-- 阻塞
  17. insert into book VALUE(8,'N00081','Eric',1.1);-- 阻塞
  18. insert 锁住区间 (18,无穷大)
  19. 2】、主键范围未命中
  20. 事务1
  21. begin;
  22. select * from book where id < 26 for update;
  23. 事务二、
  24. select * from book where id > 18 for update; -- 阻塞
  25. select * from book where id < 25 for update; -- 阻塞
  26. select * from book where id < -1 for update; -- 阻塞
  27. select * from book where id = 24 for update; -- 不阻塞
  28. select * from book where id = 25 for update; -- 阻塞
  29. select * from book where id = 30 for update; -- 阻塞
  30. select * from book where id > 26 for update; -- 阻塞
  31. select * from book where id > 30 for update; -- 不阻塞
  32. UPDATE book SET score = 9.2 WHERE id = 26; -- (update和select同理)
  33. select、update、delte 锁住区间 等于101825 和 id 在 > (负无穷大,29] 区间阻塞,id 在 < (负无穷大,正无穷大) 区间阻塞,但不包括 不存在的值等于操作
  34. -----------------------------------------------------------------------------------------
  35. insert into book VALUE(-1,'N00051','Jim',1.1);-- 阻塞
  36. insert into book VALUE(8,'N00081','Eric',1.1);-- 阻塞
  37. insert 锁住区间 (负无穷大,31)
  38. 3】、多个主键取范围
  39. 事务一、
  40. begin;
  41. select * from book WHERE id >=18 and id <41 for update;
  42. 事务二、
  43. select * from book where id > 1 for update; -- 阻塞
  44. select * from book where id < 11 for update; -- 阻塞
  45. select * from book where id < 10 for update; -- 不阻塞
  46. select * from book where id = 10 for update; -- 不阻塞
  47. select * from book where id = 11 for update; -- 不阻塞
  48. select * from book where id > 8 for update; -- 阻塞
  49. select * from book where id >= 49 for update; -- 不阻塞
  50. select * from book where id > 41 for update; -- 不阻塞
  51. select * from book where id = 35 for update; -- 阻塞
  52. select * from book where id = 40 for update; -- 阻塞
  53. select * from book where id > 30 for update; -- 不阻塞
  54. select * from book where id < 88 for update; -- 阻塞
  55. UPDATE book SET score = 9.2 WHERE id = 26; -- (update和select同理)
  56. select、update、delte 锁住区间 等于18253041 和 id 在 > (负无穷大,40]区间会阻塞 , id在<[11,正无穷大)会阻塞 但不包括 不存在的值等于操作
  57. -----------------------------------------------------------------------------------------
  58. insert into book VALUE(18,'N00051','Jim',1.1);-- 阻塞
  59. insert into book VALUE(41,'N00081','Eric',1.1);-- 阻塞
  60. insert 锁住区间 [18,41]
  61. 4】、多个不存在主键取范围
  62. 事务一、
  63. begin;
  64. select * from book where id > 19 and id < 31 for update;
  65. 事务二、
  66. select、update、delte 锁住区间 等于253041 和 id 在 > (负无穷大,40] 区间阻塞,id 在 < [19,正无穷大) 区间阻塞,
  67. -----------------------------------------------------------------------------------------
  68. insert 锁住区间 (18,41]
  69. 5】、一个存在与不存在主键取范围
  70. 事务一、
  71. begin;
  72. select * from book WHERE id >18 and id <29 for update;
  73. 事务二、
  74. select、update、delte 锁住区间 等于2530 和 id 在 > (负无穷大,29] 区间阻塞,id 在 < [18,正无穷大) 区间阻塞,
  75. -----------------------------------------------------------------------------------------
  76. insert 锁住区间 [19,30]

8、二级唯一索引 范围

  1. 1】二级唯一索引命中
  2. 事务一、
  3. begin;
  4. select * from book WHERE isbn < 'N0004' for update;
  5. 事务二、
  6. select、update、delte 锁住区间 等于N0001 N0002 N0003 N0004 N0005 N0008 和 isbn 在 > (负无穷大,'N0008'] 区间阻塞,isbn 在 < ['N0001',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  7. -------------------------------------------------------------------------------------
  8. insert 锁住区间 (负无穷大,正无穷大]
  9. 2】二级唯一索引没命中
  10. 事务一、
  11. begin;
  12. select * from book WHERE isbn < 'N00031' for update;
  13. 事务二、
  14. select、update、delte 锁住区间 等于N0001 N0002 N0003 N0004 N0005 N0008 和 isbn 在 > (负无穷大,'N0008'] 区间阻塞,isbn 在 < ['N0001',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  15. -------------------------------------------------------------------------------------
  16. insert 锁住区间 (负无穷大,正无穷大]
  17. 3】多个二级唯一索引命中
  18. 事务一、
  19. begin;
  20. select * from book WHERE isbn > 'N0003' and isbn < 'N0005' for update;
  21. 事务二、
  22. select、update、delte 锁住区间 等于 N0004 N0005 和 isbn 在 > (负无穷大,'N0005'] 区间阻塞,isbn 在 < ['N0003',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  23. -------------------------------------------------------------------------------------
  24. insert 锁住区间 ('N0003',正无穷大)
  25. 4】多个二级唯一索引没命中
  26. 事务一、
  27. begin;
  28. select * from book WHERE isbn > 'N00021' and isbn < 'N00049' for update;
  29. 事务二、
  30. select、update、delte 锁住区间 等于 N0003 N0004 N0005 和 isbn 在 > (负无穷大,'N0005') 区间阻塞,isbn 在 < ['N0003',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  31. -----------------------------------------------------------------------------------------
  32. insert 锁住区间 ('N0002','N0005')
  33. 5】一个二级唯一索引没命中和一个二级索引命中
  34. 事务一、
  35. begin;
  36. select * from book WHERE isbn > 'N0002' and isbn < 'N00049' for update;
  37. 事务二、
  38. select、update、delte 锁住区间 等于 N0003 N0004 N0005 和 isbn 在 > (负无穷大,'N0005') 区间阻塞,isbn 在 < ['N0002',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  39. -----------------------------------------------------------------------------------------
  40. insert 锁住区间 ('N0002','N0005')

9、二级索引 范围

  1. 1】单个命中
  2. 1、事务1
  3. begin;
  4. select * from book WHERE author < 'Eric' for update;
  5. 2、事务2
  6. select、update、delte 锁住区间 等于 Alice Bob Eric 和 author 在 > (负无穷大,'Jim'] 区间阻塞,author 在 < [负无穷大,正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  7. ----------------------------------------------------------------------------------------
  8. insert 锁住区间 (负无穷大,'Eric')
  9. 30 N0004 Eric 9.1
  10. 注意:
  11. 如果在author = 'Eric'情况下, insert into book VALUE(29,'N00049','Eric',1.1);在主键id < 30情况下会阻塞。
  12. insert into book VALUE(31,'N00049','Eric',1.1); --不会阻塞
  13. 2】单个没命中
  14. 事务1
  15. begin;
  16. select * from book WHERE author < 'Ca' for update;
  17. 事务2
  18. select、update、delte 锁住区间 等于 Alice Bob Eric 和 author 在 > (负无穷大,'Jim'] 区间阻塞,author 在 < [负无穷大,正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  19. ----------------------------------------------------------------------------------------
  20. insert 锁住区间 (负无穷大,'Eric')
  21. insert into book VALUE(29,'N00049','Eric',1.1);在主键id < 30情况下会阻塞。
  22. insert into book VALUE(31,'N00049','Eric',1.1); --不会阻塞
  23. 3】多个命中
  24. 事务1
  25. begin;
  26. select * from book WHERE author > 'Bob' and author < 'Jim' for update;
  27. 事务2
  28. select、update、delte 锁住区间 等于 Eric Jim 和 author 在 > (负无穷大,'Jim'] 区间阻塞,author 在 < [Bob,正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  29. ----------------------------------------------------------------------------------------
  30. insert 锁住区间 ('Bob','Jim')
  31. 当author = 'Bob'时,会阻塞id>10记录,id < 10 不会阻塞
  32. 当author = 'Jim'时,会阻塞id<25记录,id > 25 不会阻塞
  33. 4】一个命中和一个未命中
  34. 事务1
  35. begin;
  36. select * from book WHERE author > 'Bob' and author < 'Ki' for update;
  37. 事务2
  38. select、update、delte 锁住区间 等于 Eric Jim Tom 和 author 在 > (负无穷大,'Tom'] 区间阻塞,author 在 < [Bob,正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  39. ----------------------------------------------------------------------------------------
  40. insert 锁住区间 ('Bob','Jim')
  41. 当author = 'Bob'时,会阻塞id>10记录,id < 10 不会阻塞
  42. 当author = 'Tom'时,会阻塞id<41记录,id > 41 不会阻塞
  43. 5】多个未命中
  44. 事务1
  45. begin;
  46. select * from book WHERE author > 'Alice1' and author < 'Ki' for update;
  47. 事务2
  48. select、update、delte 锁住区间 等于 Alice Bob Eric Jim Tom 和 author 在 > (负无穷大,'Tom'] 区间阻塞,author 在 < ['Alice',正无穷大) 区间阻塞.但不包括 不存在的值等于操作
  49. ----------------------------------------------------------------------------------------
  50. insert 锁住区间 (负无穷大,正无穷大)

10、组合索引 todo

  1. 1、事务1
  2. start TRANSACTION;
  3. select * from book where author = 'Tom' and score = 8.3 for update;
  4. 2、事务2
  5. start TRANSACTION;
  6. select * from book where author = 'Bob' for update;#不阻塞
  7. start TRANSACTION;
  8. select * from book where author = 'Tom' for update; #阻塞
  9. start TRANSACTION;
  10. select * from book where score = 7.7 for update;#不阻塞
  11. start TRANSACTION;
  12. select * from book where score = 8.3 for update;#阻塞
  13. 总结
  14. 对score 排序后
  15. 41 N0005 Tom 2.2
  16. 10 N0001 Bob 3.4
  17. 25 N0003 Jim 5
  18. 18 N0002 Alice 7.7
  19. 49 N0006 Tom 8.3
  20. 60 N0007 Rose 8.9
  21. 30 N0004 Eric 9.1
  22. todo 猜想只是相当于行锁

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/998365
推荐阅读
相关标签
  

闽ICP备14008679号