微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

InnoDB行锁的实现方法

本篇内容主要讲解“InnoDB行锁的实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“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进行类型转换,而执行的全表扫描。

  1. MysqL> alter table tab_no_index add index name(name);

  2. Query OK, 4 rows affected (8.06 sec)

  3. Records: 4  Duplicates: 0  Warnings: 0

  4. MysqL> explain select * from tab_with_index where name = 1 \G

  5. *************************** 1. row ***************************

  6.            id: 1

  7.   select_type: SIMPLE

  8.         table: tab_with_index

  9.          type: ALL

  10. possible_keys: name

  11.           key: NULL

  12.       key_len: NULL

  13.           ref: NULL

  14.          rows: 4

  15.         Extra: Using where

  16. 1 row in set (0.00 sec)

  17. MysqL> explain select * from tab_with_index where name = '1' \G

  18. *************************** 1. row ***************************

  19.            id: 1

  20.   select_type: SIMPLE

  21.         table: tab_with_index

  22.          type: ref

  23. possible_keys: name

  24.           key: name

  25.       key_len: 23

  26.           ref: const

  27.          rows: 1

  28.         Extra: Using where

  29. 1 row in set (0.00 sec)

到此,相信大家对“InnoDB行锁的实现方法”有了更深的了解,不妨来实际操作一番吧!这里是编程之家网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐