共计 2670 个字符,预计需要花费 7 分钟才能阅读完成。
本篇内容主要讲解“InnoDB 行锁的实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“InnoDB 行锁的实现方法”吧!
session_1
session_2
mysql set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql select * from tab_no_index where id = 1 ;
+——+——+
| id | name |
+——+——+
| 1 | 1 |
+——+——+
1 row in set (0.00 sec)
mysql set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql select * from tab_no_index where id = 2 ;
+——+——+
| id | name |
+——+——+
| 2 | 2 |
+——+——+
1 row in set (0.00 sec)
mysql select * from tab_no_index where id = 1 for update;
+——+——+
| id | name |
+——+——+
| 1 | 1 |
+——+——+
1 row in set (0.00 sec)
mysql select * from tab_no_index where id = 2 for update;
等待
在如表 20- 9 所示的例子中,看起来 session_1 只给一行加了排他锁,但 session_2 在请求其他行的排他锁时,却出现了锁等待!原因就是在没有索引的情况下,InnoDB 只能使用表锁。当我们给其增加一个索引后,InnoDB 就只锁定了符合条件的行,如表 20-10 所示。
session_1
session_2
mysql set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql select * from tab_with_index where id = 1 ;
+——+——+
| id | name |
+——+——+
| 1 | 1 |
+——+——+
1 row in set (0.00 sec)
mysql set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql select * from tab_with_index where id = 2 ;
+——+——+
| id | name |
+——+——+
| 2 | 2 |
+——+——+
1 row in set (0.00 sec)
mysql select * from tab_with_index where id = 1 for update;
+——+——+
| id | name |
+——+——+
| 1 | 1 |
+——+——+
1 row in set (0.00 sec)
mysql select * from tab_with_index where id = 2 for update;
+——+——+
| id | name |
+——+——+
| 2 | 2 |
+——+——+
1 row in set (0.00 sec)
(2)由于 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。
在如表 20-11 所示的例子中,表 tab_with_index 的 id 字段有索引,name 字段没有索引:
表 20-11 InnoDB 存储引擎使用相同索引键的阻塞例子
在如表 20-12 所示的例子中,表 tab_with_index 的 id 字段有主键索引,name 字段有普通索引:
表 20-12 InnoDB 存储引擎的表使用不同索引的阻塞例子
在下面的例子中,检索值的数据类型与索引字段不同,虽然 MySQL 能够进行数据类型转换,但却不会使用索引,从而导致 InnoDB 使用表锁。通过用 explain 检查两条 SQL 的执行计划,我们可以清楚地看到了这一点。
div align= left font-size:14px;white-space:normal;background-color:#FFFFFF;
例子中 tab_with_index 表的 name 字段有索引,但是 name 字段是 varchar 类型的,如果 where 条件中不是和 varchar 类型进行比较,则会对 name 进行类型转换,而执行的全表扫描。
mysql alter table tab_no_index add index name(name);
Query OK, 4 rows affected (8.06 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql explain select * from tab_with_index where name = 1 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tab_with_index
type: ALL
possible_keys: name
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra: Using where
1 row in set (0.00 sec)
mysql explain select * from tab_with_index where name = 1 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tab_with_index
type: ref
possible_keys: name
key: name
key_len: 23
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
到此,相信大家对“InnoDB 行锁的实现方法”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!