• ADADADADAD

    Mysql锁之行级锁和表级意向锁[ mysql数据库 ]

    mysql数据库 时间:2024-12-24 19:10:06

    作者:文/会员上传

    简介:

    Innodb存储引擎实现了两种行级锁:l 共享锁l 排他锁这两种锁之间的兼容关系如下图所示共享锁排他锁共享锁兼容不兼容排他锁不兼容不兼容关于行级锁比较容易理解。下面介绍一下

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

    Innodb存储引擎实现了两种行级锁:

    l 共享锁

    l 排他锁

    这两种锁之间的兼容关系如下图所示


    共享锁

    排他锁

    共享锁

    兼容

    不兼容

    排他锁

    不兼容

    不兼容

    关于行级锁比较容易理解。下面介绍一下表级意向锁。

    Innodb存储引擎支持多粒度的锁定,换句话说,允许事务在表级和行级上同时持有锁。意向锁是一种表级锁,它是由存储引擎自己维护的,不需要用户手动命令干预。如果事务想要给表中几行数据加上行级共享锁,那么需要先在表级别加上意向共享锁(IS);如果事务想要给表中几行数据加上行级排他锁,那么需要先在表级别加上意向排他锁(IX)。那么这两种表级锁有什么意义呢?

    比如存在这样一种情况。一个会话A开启如下事务,在表中的一行上面加上一行排他锁,并且没有提交。

    mysql>begin;

    Query OK, 0rows affected (0.00 sec)

    mysql>SELECT * FROM t_compact WHERE c1 = 'a' FOR UPDATE;

    +------+------+------+

    | c1 | c2| c3 |

    +------+------+------+

    | a | aa| aaa |

    +------+------+------+

    1 row in set(0.00 sec)

    会话B需要给表加一个读锁,比如lock tables t_compact read;那么就要在表级别加共享锁。加锁之前需要确认一件事,那就是表中的所有的行上面都没有排他锁,否则会出现行锁和表锁的共存冲突问题。如果没有表级意向锁的话,那么会话B需要去每一行检查是否存在行级排他锁,所以意向表级锁就是用来缩短这个检查过程的。它将检查每一行的排他锁变成了只要检查一个表级锁就可以了。

    存在意向锁之后,整个过程变成了这样:会话A在以排他锁锁住一行之前,需要先加一个表级别的意向排他锁,成功之后再在需要锁住的那一行上面加行级排他锁。这时会话B需要在表级别加共享锁,这时它发现表上已经存在意向排他锁,那么说明表中已经有数据行上有行级排他锁,那么会话B就需要等待。

    表级意向锁相互之间是完全兼容的。


    IS

    IX

    IS

    兼容

    兼容

    IX

    兼容

    兼容

    关于表级意向锁互相兼容,下面的列子可以帮助理解。

    仍然是表t_compact,注意表上存在一个主键

    mysql> show create table t_compact\G

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

    Table: t_compact

    Create Table: CREATE TABLE `t_compact` (

    `c1` varchar(10) NOT NULL,

    `c2` char(10) DEFAULT NULL,

    `c3` varchar(10) DEFAULT NULL,

    PRIMARY KEY (`c1`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

    会话A,在一行上即行级排他锁

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

    mysql> select * FROM t_compact WHEREc1 = 'a' FOR UPDATE;

    +----+------+------+

    | c1 | c2 | c3|

    +----+------+------+

    | a| aa | aaa |

    +----+------+------+

    1 row in set (0.00 sec)

    会话B,在另一行上加行级排他锁。由于会话A的缘故,表上已经存在意向排他锁,会话B也需要在表上加意向排他锁,由于意向锁的兼容性,意向排他锁也是可以加的上去的。下面再去检查c1 = 'b'行上有没有行级排他锁,经检查没有行级排他锁,那么c1 = 'b'上加行级排他锁,不会阻塞。

    可是如果会话B也要在c1 = 'a'上加行级排他锁,那么加完意向排他锁之后,检查行级排他锁就会发现已经存在,那么就会被阻塞。

    所以,这种兼容性有助于提高并发能力。

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

    mysql> select * FROM t_compact WHEREc1 = 'b' FOR UPDATE;

    +----+------+------+

    | c1 | c2 | c3|

    +----+------+------+

    | b| bb | bbb |

    +----+------+------+

    1 row in set (0.00 sec)

    综合一下行级锁和意向表级锁的兼容性


    S

    X

    IS

    IX

    S

    兼容

    不兼容

    兼容

    不兼容

    X

    不兼容

    不兼容

    不兼容

    不兼容

    IS

    兼容

    不兼容

    兼容

    兼容

    IX

    不兼容

    不兼容

    兼容

    兼容

    Mysql锁之行级锁和表级意向锁.docx

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

    推荐度:

    下载
    热门标签: mysql之行意向