InnoDB行锁的实现方法

46次阅读
没有评论

共计 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 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-01发表,共计2670字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)