• ADADADADAD

    InnoDB行锁的实现方法[ mysql数据库 ]

    mysql数据库 时间:2024-11-28 13:03:52

    作者:文/会员上传

    简介:

    session_1session_2mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_no_index where id = 1 ;+------+------+| id | name |+-----

    以下为本文的正文内容,内容仅供参考!本站为公益性网站,复制本文以及下载DOC文档全部免费。

    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-11InnoDB存储引擎使用相同索引键的阻塞例子

    在如表20-12所示的例子中,表tab_with_index的id字段有主键索引,name字段有普通索引:

    表20-12InnoDB存储引擎的表使用不同索引的阻塞例子

    在下面的例子中,检索值的数据类型与索引字段不同,虽然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: 4Duplicates: 0Warnings: 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行锁的实现方法.docx

    将本文的Word文档下载到电脑

    推荐度:

    下载
    热门标签: innodb