Mysql在InnoDB引擎下索引失效行級鎖變表鎖案例


先做好准備,創建InnoDB引擎數據表,並添加了相應的索引

DROP TABLE IF EXISTS `innodb_lock`; CREATE TABLE `innodb_lock` ( `a` int(10) NOT NULL, `b` varchar(255) NOT NULL DEFAULT '', KEY `index_a` (`a`), KEY `index_b` (`b`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- ----------------------------
-- Records of innodb_lock -- ---------------------------- INSERT INTO `innodb_lock` VALUES ('1', 'b2'); INSERT INTO `innodb_lock` VALUES ('3', '3'); INSERT INTO `innodb_lock` VALUES ('4', '4000'); INSERT INTO `innodb_lock` VALUES ('5', '5000'); INSERT INTO `innodb_lock` VALUES ('6', '6000'); INSERT INTO `innodb_lock` VALUES ('7', '7000'); INSERT INTO `innodb_lock` VALUES ('8', '8000'); INSERT INTO `innodb_lock` VALUES ('9', '9000'); INSERT INTO `innodb_lock` VALUES ('1', 'b1');

然后分別打開兩個Mysql終端,設置autocommit自動提交為0,也就是關閉自動提交功能,事務隔離級別處於可重復讀狀態;查看一下表數據。

MySQL [test_db]> set autocommit = 0;
MySQL [test_db]> select * from innodb_lock; +---+------+
| a | b    |
+---+------+
| 1 | b2   |
| 3 | 3    |
| 4 | 4000 |
| 5 | 5000 |
| 6 | 6000 |
| 7 | 7000 |
| 8 | 8000 |
| 9 | 9000 |
| 1 | b1   |
+---+------+

接下來在第一個終端執行update語句

MySQL [test_db]> update innodb_lock set b ='4001' where a = 4;

然后第二個終端執行update語句

MySQL [test_db]> update innodb_lock set b = '4004' where a = 4;

發現第二個終端處於阻塞狀態,因為這里修改的是同一行數據,只有在第一個終端提交之后,鎖被釋放,第二個終端執行完了SQL,最后第二個終端也commit提交之后數據才會更改,b的值為'4004'。

我們繼續

在第一個終端執行update語句

MySQL [test_db]> update innodb_lock set b='4005' where a = 4;

然后第二個終端執行update語句

MySQL [test_db]> update innodb_lock set b = '9001' where a = 9;

發現兩條語句都執行成功了。因為修改的不是同一行數據。然后分別commit提交,再查看下數據,發現兩行數據都發生了變化。

MySQL [test_db]> select * from innodb_lock; +---+------+
| a | b    |
+---+------+
| 1 | b2   |
| 3 | 3    |
| 4 | 4005 |
| 5 | 5000 |
| 6 | 6000 |
| 7 | 7000 |
| 8 | 8000 |
| 9 | 9001 |
| 1 | b1   |
+---+------+

 

下面是重點,兩個終端還是分別操作不同的行。

在第一個終端執行update操作

MySQL [test_db]> update innodb_lock set a = 41 where b =4005;  //注意這里的where條件b=4005。要記得當前表的b字段是字符串類型,並且加了索引,加了索引之后如果查詢條件沒加引號會導致失效

然后在第二個終端執行update操作

MySQL [test_db]> update innodb_lock set b='9002' where a = 9; //發現被阻塞,行鎖邊表鎖

一定要注意索引的合理利用!~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM