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),同意事务读取一行数据. ? ...
随机推荐
- OpenSCA技术原理之npm依赖解析
本文主要介绍基于npm包管理器的组件成分解析原理. npm 介绍 npm(全称Node Package Manager)是Node.js的预设软件包管理器. npm的依赖管理文件是package.js ...
- 数字孪生智慧物流之 Web GIS 地图应用
前言 随着数字经济时代的来临,新一轮全球化进程速度加快,在大数据.人工智能.物联网等高新技术深度融合下,加快催化智慧物流发展,引领物流行业划入全新时代. 从物流运输到货物分拣再到站点配送,图扑软件数据 ...
- 微前端qiankun
- python之HtmlTestRunner(二)view无法打开问题解决
默认使用python之HtmlTestRunner会遇到测试报告中的view无法打开的情况 view打不开的情况解决 打开\Lib\site-packages\HtmlTestRunner\templ ...
- MetaGPT day02: MetaGPT Role源码分析
MetaGPT源码分析 思维导图 MetaGPT版本为v0.4.0,如下是from metagpt.roles import Role,Role类执行Role.run时的思维导图: 概述 其中最重要的 ...
- 线性代数 · 矩阵 · Matlab | Moore-Penrose 伪逆矩阵代码实现
背景 - Moore-Penrose 伪逆矩阵: 对任意矩阵 \(A\in\mathbb C^{m\times n}\) ,其 Moore-Penrose 逆矩阵 \(A^+\in\mathbb C^ ...
- 12-Verilog-同步FIFO设计
同步FIFO和异步FIFO FIFO分为一个同步FIFO,一个异步FIFO,FIFO有读口和写口 读写时钟是一个,就是同步FIFO;读写时钟不是一个,异步FIFO IP核设计中,一般使用同步FIFO设 ...
- 你老了,别搞IT了……
你老了,别搞IT了-- [来源]
- [转帖]MySQL的版本情况
Introducing MySQL Innovation and Long-Term Support (LTS) versions (oracle.com) Introducing MySQL Inn ...
- [转帖]Web技术(六):QUIC 是如何解决TCP 性能瓶颈的?
文章目录 一.QUIC 如何解决TCP的队头阻塞问题? 1.1 TCP 为何会有队头阻塞问题 1.2 QUIC 如何解决队头阻塞问题 1.3 QUIC 没有队头阻塞的多路复用 二.QUIC 如何优化T ...