InnoDB存储引擎的行级锁
InnoDB存储引擎的行级锁
InnoDB存储引擎和MyISAM的其中有两个很重要的区别:一个是事务,一个就是锁机制不同。事务之前有介绍,有问题的去补课;锁方面的不同是InnoDB引擎既有表锁又有行锁,表锁的应用和MyISAM表锁用法一样,行锁只有通过有索引的字段作为条件检索的时候,才会使用行级锁,反之则是表锁。
一、隐式加锁
创建表和测试数据
用户表user中id为主键索引,username为普通索引,money字段为普通字段。在非事务环境下,隐式加锁的过程时间非常短,不便研究。下面的栗子都是在事务环境下
CREATE TABLE `user`(
id INT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(50),
`money` DECIMAL(7,2),
key username(username)
)ENGINE=innodb CHARSET=utf8;
INSERT INTO user(`username`,`money`) VALUES('乔峰',5);
INSERT INTO user(`username`,`money`) VALUES('风清扬',20);
INSERT INTO user(`username`,`money`) VALUES('聂哥',88);
1、行锁
当我们对用户表进行增删改(insert、delete、update)的时候,如果有检索条件中使用到了索引,MySQL服务器会自动给当前操作的表添加行锁。
A端
更新id为3的记录,id为主键索引,所以会引发行级锁。
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update user set money=money+5 where id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
B端在执行update操作的时候,先是光标不停闪烁,且进入锁等待状态,后报锁超时错误
mysql> update user set money=money+5 where id=1;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update user set money=money+12 where id=3;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
A端
A端执行提交(commit),系统会自动释放表锁
mysql> commit;
Query OK, 0 rows affected (0.03 sec)
2、表锁
如果有检索条件(money字段)中没有使用到了索引,MySQL服务器会自动给当前操作的表添加表锁。
A端
mysql> select * from user;
+----+----------+-------+
| id | username | money |
+----+----------+-------+
| 1 | 乔峰 | 10.00 |
| 2 | 风清扬 | 20.00 |
| 3 | 聂哥 | 93.00 |
+----+----------+-------+
3 rows in set (0.02 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update user set money=money+5 where money=93.00;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
B端
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update user set money=money+12 where id=2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> update user set money=money+12 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>
二、显式加行锁
加锁语句:
SELECT 查询语句 LOCK IN SHARE MODE | FOR UPDATE
我们只需在正常的查询语句后面加LOCK IN SHARE MODE | FOR UPDATE就能实现添加行级读锁和行级排他锁
1、意向锁
意向锁是InnoDB自动加的,不需用户干预,对于UPDATE、DELETE、INSERT操作,InnoDB会自动给操作的数据加排他锁。 我们在显式加行锁的时候,MySQL服务器会自动给操作表添加一个意向锁。此意向锁是隐式添加的,多个意向锁之间不会产生冲突且相互兼容
2、锁的兼容问题
| - | 共享锁 | 排他锁 | 意向共享锁 | 意向排他锁 |
|---|---|---|---|---|
| 共享锁 | 兼容 | 冲突 | 兼容 | 冲突 |
| 排他锁 | 冲突 | 冲突 | 冲突 | 冲突 |
2.1、共享锁兼容
A端
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user lock in share mode;
+----+----------+-------+
| id | username | money |
+----+----------+-------+
| 1 | 乔峰 | 10.00 |
| 2 | 风清扬 | 20.00 |
| 3 | 聂哥 | 98.00 |
+----+----------+-------+
3 rows in set (0.00 sec)
B端
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user lock in share mode;
+----+----------+-------+
| id | username | money |
+----+----------+-------+
| 1 | 乔峰 | 10.00 |
| 2 | 风清扬 | 20.00 |
| 3 | 聂哥 | 98.00 |
+----+----------+-------+
3 rows in set (0.00 sec)
2.2、共享锁和意向排他锁冲突
A端
mysql> select * from user where id=3 lock in share mode;
+----+----------+-------+
| id | username | money |
+----+----------+-------+
| 3 | 聂哥 | 98.00 |
+----+----------+-------+
1 row in set (0.00 sec)
mysql> update user set money=money+5 where id=3;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
2.3、排他锁与其他锁都冲突
A端
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where id=3 for update;
+----+----------+--------+
| id | username | money |
+----+----------+--------+
| 3 | 聂哥 | 103.00 |
+----+----------+--------+
1 row in set (0.00 sec)
B端
mysql> select * from user where id=3 lock in share mode;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> update user set money=money+5 where id=3;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
三、间隙锁
间隙锁是针对一个范围条件的检索时,InnoDB会给符合条件的已有的数据记录的索引项加锁;对于键值在条件范围内但是并不存在的记录,叫做“间隙”,InnoDB也会对这个“间隙”加锁,这种锁机制就是间隙锁
A端
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where id > 2 for update;
+----+----------+--------+
| id | username | money |
+----+----------+--------+
| 3 | 聂哥 | 103.00 |
+----+----------+--------+
1 row in set (0.00 sec)
B端
mysql> update user set money=money+5 where id=3;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> INSERT INTO user(`username`,`money`) VALUES('jack',99);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
InnoDB存储引擎的行级锁的更多相关文章
- 三分钟入门 InnoDB 存储引擎中的表锁和行锁
各位对 "锁" 这个概念应该都不是很陌生吧,Java 语言中就提供了两种锁:内置的 synchronized 锁和 Lock 接口,使用锁的目的就是管理对共享资源的并发访问,保证数 ...
- InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!
InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的. InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoD ...
- mysql中InnoDB存储引擎的行锁和表锁
Mysql的InnoDB存储引擎支持事务,默认是行锁.因为这个特性,所以数据库支持高并发,但是如果InnoDB更新数据的时候不是行锁,而是表锁的话,那么其并发性会大打折扣,而且也可能导致你的程序出错. ...
- MySQL技术内幕InnoDB存储引擎(六)——锁
什么是数据库的锁? 锁是数据库系统区别于文件系统的一个关键特性.锁机制用于管理对共享资源的并发访问.让数据库事务满足隔离性的要求. InnoDB 中锁的作用 不仅用于对数据进行并发访问,还还包括了缓冲 ...
- Mysql的行级锁与表级锁
在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM ...
- Mariadb之显式使用表锁和行级锁
首先我们来看看mariadb的锁定概念,所谓锁就是当一个进程或事务在操作某一资源时,为了防止其他用户或者进程或事务对其进行资源操作,导致资源抢占而发生冲突,通常在A进程操作该资源时,会对该资源进行加锁 ...
- InnoDB存储引擎
[InnoDB和MyISAM区别][ http://jeck2046.blog.51cto.com/184478/90499] InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型, ...
- 【MySQL】MySQL(四)存储引擎、索引、锁、集群
MySQL存储引擎 MySQL体系结构 体系结构的概念 任何一套系统当中,每个部件都能起到一定的作用! MySQL的体系结构 体系结构详解 客户端连接 支持接口:支持的客户端连接,例如C.Java.P ...
- MySQL InnoDB存储引擎中的锁机制
1.隔离级别 Read Uncommited(RU):这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用. Read Committed (RC):仅能读取到已提交 ...
- MySQL 温故而知新--Innodb存储引擎中的锁
近期碰到非常多锁问题.所以攻克了后,细致再去阅读了关于锁的书籍,整理例如以下:1,锁的种类 Innodb存储引擎实现了例如以下2种标准的行级锁: ? 共享锁(S lock),同意事务读取一行数据. ? ...
随机推荐
- HHKB 键盘布局记录以及一些闲言碎语
HHKB (happy hacking keyboard) 是世界顶级键盘品牌,自 1996 年推出以来畅销至今.与其他键盘不同,HHKB 机身小巧,省略了 F1 - F12 功能键.光标键和 Pag ...
- vue子页面给App.vue传值
前端工程现在变成了单页面富文本的模式,整体布局定下来后,跳转只在<router-view>中展示,外层的布局不容易改变.最近发现有如下这个方法可以直接传值给App.vue,经过实践确实可以 ...
- 4 Englishi 词根
11 -ism N词后缀 ...主义: 流派: 特性 individualism captitalism modernism humanism 12 -ist N词后缀 人: ...家 art ...
- C#绘制柱形图
柱形图数据 通过 panel 绘制柱形图 private void ShowPic() { Conn(); //打开数据库连接 using (cmd = new SqlCommand("SE ...
- python之logging日志
一.logging介绍: 使用 logging.debug(text)来打印信息,info等的使用方法与debug一致,都只有一个位置参数 默认日志界别为:会输出warning以上的信息,代码示例: ...
- docker 原理之 namespace (上)
1. namespace 资源隔离 namespace 是内核实现的一种资源隔离技术,docker 使用 namespace 实现了资源隔离. Liunx 内核提供 6 种 namespace 隔离的 ...
- MySQL 查询索引失效及如何进行索引优化
本文为博主原创,未经允许不得转载: 我们都知道创建索引的目的是快速从整体集合中选择性地读取满足条件的一部分集合.mysql中一张表是可以支持多个索引的.但是,你写sql语句的时候,并没有主动指定使用哪 ...
- 基于python+django的外卖点餐网站-外卖点餐系统
该系统是基于python+django开发的外卖点餐系统.适用场景:大学生.课程作业.毕业设计.学习过程中,如遇问题可以在github给作者留言. 演示地址 前台地址: http://food.git ...
- 如何在Typora中跳转到文本内的指定位置?
1.问题 网上写的使用HTML锚点,在typora并不适用 如 跳转 你好 2.解决 参考链接 https://segmentfault.com/q/1010000018057010 https:// ...
- VSCODE配置tasks.json
1.新建配置任务tasks.json 选择gcc.exe 可以在其中按需修改 { "version": "2.0.0", "tasks": ...