设为首页 加入收藏

TOP

innodb的锁讲解(一)
2019-03-05 16:09:42 】 浏览:244
Tags:innodb 讲解
innodb的锁,我们可以从几个维度来分析,分为级别,类型

级别

行级锁

表级锁

类型

共享锁(S),也称为写锁, 级别:行级锁

意向共享锁(IS),也称为意向写锁 级别:表级锁

排他锁(X),也称为读锁 属于行级锁 级别: 行级锁

意向排他锁(IX),也称为意向读锁 级别: 表级锁

行锁的算法

Record Locks

Gap Locks

Next-Key Locks

Insert intention Locks

AUTO-INC Locks

Predicate Locks for Spatial Indexes

锁的兼容性请看下图

innodb的锁讲解

我们就先从类型讲起

共享锁

允许持有锁的事务读取行

假如有一个a事务获取了x行的共享锁,这时候b事务也来请求x行的锁,那么会进行一下处理

如果b请求的是x行的共享锁,那么会立刻授予,这时候a事务和b事务都拥有x行的共享锁

如果b请求的是x的排他锁,那么不会立刻授予,因为共享锁和排他锁是不兼容的

排他锁

允许持有锁的事务更新或删除行。

假如有一个a事务获取了x行的排他锁,这时候b事务也来请求x行的锁,这时候不管b事务请求的锁是共享锁还是排他锁,都不能立即授予,只能等到a事务释放了在x行的排他锁才能授予b事务,因为排他锁与任何的锁都不兼容

意向锁的讲述

innodb支持多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同行存在,为了支持在不同粒度上进行操作,innodb存储引擎支持一个额外的锁方式,称之为意向锁,意向锁是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度上进行加锁,也就是如果一个事务需要针对记录R来加排他锁,那么就需要对记录R所在的数据库,表,页进行加锁,最后对记录R加排他锁,如果有任何一个部分导致等待,那么该操作需要粗粒度锁的完成。

意向锁是表级锁,设计目的主要是为了在下一个事务中揭示下一行将被请求的锁类型,由于innodb存储引擎支持的是行级别的锁,因此意向锁其实不会阻塞除全表扫描以外的任何请求。

上面的可能不好理解,下面我说一个实际的例子

我们有一个student表

mysql> show create table student;

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

| Table | Create Table |

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

| student | CREATE TABLE student (

id int(11) NOT NULL AUTO_INCREMENT,

student_num int(11) NOT NULL DEFAULT '0' COMMENT '学号',

name varchar(32) NOT NULL DEFAULT '' COMMENT '学生姓名',

PRIMARY KEY (id),

UNIQUE KEY uqidx_student_num (student_num)

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 |

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

1 row in set (0.00 sec)

mysql> select * from student;

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

| id | student_num | name |

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

| 1 | 1 | zhangsan |

| 2 | 2 | lisi |

| 3 | 3 | wangwu |

| 4 | 4 | zhaoliu |

| 5 | 5 | liqi |

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

5 rows in set (0.00 sec)

session1

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from student where student_num=4 for update;

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

| id | student_num | name |

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

| 4 | 4 | zhaoliu |

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

1 row in set (0.00 sec)

session2

mysql> LOCK TABLE student write;

这时候我们发现session2一直在等待,因为session2想获取student整个表的写锁,如果session2申请成功了, 它是可以修改student表的任意一行的,那么大家会说session1已经获取了student_num=4的排他锁呢,如果session2申请成功了,那么student_num=4的记录也会被session2修改了,所以说这时候session2肯定是会阻塞的,那么数据库是根据什么方法来判断使得session2被阻塞呢,无非就下面两种方法

判断这个表是否被其他事务用表锁给锁住

判断这个表的每一行是否有

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇MySQL基础解析 下一篇事务隔离级别

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目