mysql 锁 代码_MySQL中的锁实例
表結構:
id:自增主鍵,a:無索引,b:普通索引
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(4) NOT NULL DEFAULT '0',
`b` int(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `b` (`b`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
等值查詢加鎖
主鍵索引字段加鎖查詢
窗口A:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test where id = 1 for update;
+----+---+---+
| id | a | b |
+----+---+---+
| 1 | 2 | 1 |
+----+---+---+
1 row in set (0.00 sec)
窗口B:
mysql> update test set a = 11 where id = 1;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 11 where id = 2;(正常執行)
證明根據主鍵索引字段加鎖查詢,會鎖住該條數據(記錄鎖)。
普通索引字段加鎖查詢
窗口A:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test where b = 1 for update;
+----+---+---+
| id | a | b |
+----+---+---+
| 1 | 1 | 1 |
| 3 | 3 | 1 |
| 5 | 5 | 1 |
+----+---+---+
3 rows in set (0.00 sec)
窗口B:
mysql> update test set a = 11 where b = 1;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 11 where id = 3;(被阻塞,等待窗口A中commit后才執行)
mysql> insert into test(a,b) value(1,1);(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 11 where id = 2;(正常執行)
mysql> insert into test(a,b) value(1,2);(正常執行)
證明根據普通索引字段加鎖查詢,會鎖住符合該條件的所有記錄包括不存在的,因此得出鎖的是索引,而非數據本身。
無索引字段加鎖查詢
窗口A:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test where a = 1 for update;
+----+---+---+
| id | a | b |
+----+---+---+
| 1 | 1 | 1 |
+----+---+---+
1 row in set (0.00 sec)
窗口B:
mysql> update test set a = 22 where id = 1;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 22 where a = 1;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 22 where b = 1;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 22 where a = 2;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 22 where b = 2;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 22 where id = 2;(被阻塞,等待窗口A中commit后才執行)
mysql> insert into test(a,b) value(22,22);(被阻塞,等待窗口A中commit后才執行)
證明根據無索引字段加鎖查詢,會鎖住整張表,表現形式類似于表鎖。
范圍查詢加鎖
窗口A:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test where id > 3 and id < 6 for update;
+----+---+---+
| id | a | b |
+----+---+---+
| 5 | 5 | 5 |
+----+---+---+
1 row in set (0.00 sec)
窗口B:
mysql> insert into test(id,a,b) value(4,4,4);(被阻塞,等待窗口A中commit后才執行)
mysql> insert into test(id,a,b) value(6,6,6);(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 77 where id = 7;(被阻塞,等待窗口A中commit后才執行)
mysql> update test set a = 33 where id = 3;(正常執行)
mysql> update test set a = 22 where id=8;(正常執行)
證明鎖的范圍為**(3,7],既鎖住了記錄本身(記錄鎖),也鎖住了索引之間的間隙(間隙鎖),而且把索引后相鄰的兩個記錄也鎖住了(臨鍵鎖)**。
通過無索引字段范圍查詢時,同樣是鎖住整張表。
總結
以上是生活随笔為你收集整理的mysql 锁 代码_MySQL中的锁实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 摩尔庄园紫色鲶鱼怎么钓
- 下一篇: 中卫看精子不液化最好的医院推荐