InnoDB 锁的种类之意向锁、记录锁和间隙锁

意向锁(Intention Locks; table-level lock)

意向锁是一种特殊的表级锁,意向锁是为了让 InnoDB 多粒度的锁能共存而设计的。取得行的共享锁和排他锁之前需要先取得表的意向共享锁(IS)和意向排他锁(IX),意向共享锁和意向排他锁都是系统自动添加和自动释放的,整个过程无需人工干预。

意向锁就是指未来的某一个时刻事务可能要加共享锁或者排它锁,提前声明一个意向,分为两种:

意向共享锁(Intention Shared Lock) IS

事务有意向对表中的某些行加共享锁(S锁)

-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;

意向排它锁(Intention Exclusive Lock)IX

事务有意向对表中的某些行加排他锁(X锁)

-- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;

举例

-- 要设置 IS 锁 --
select * from A where id = 1 lock in share mode;
-- 要设置 IX 锁 --
select * from A where id > 0 for update;

如果示例 1 和 2 都开启了事务,事务 1 锁住了表 A 的其中 id=1 的一行,事务 2 要获取整个表的更新锁需要进行判断

step1:判断表 A 是否有表级锁

step2:判断表 A 每一行是否有行级锁

当数据量庞大的时候 step2 这种判断十分低效,于是就有意向锁协议

意向锁协议:

事务要获取表 A 某些行的 S 锁必须要获取表 A 的 IS 锁

事务要获取表 A 某些行的 X 锁必须要获取表 A 的 IX 锁

这时候 step2 就改变成了对意向锁的判断

step2:发现表 A 有 IS 锁,说明表 A 肯定有行级的 S 锁,因此,事务 B 申请写锁阻塞等待,判断效率极大提高

记录锁(Record Locks)

官方原文

A record lock is a lock on an index record. For example, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; prevents any other transaction from inserting, updating, or deleting rows where the value of t.c1 is 10.

SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 这一行则是使用了记录锁,不允许其他事务进行增,删,改

但是 SELECT c1 FROM t WHERE c1 = 10; 是没有锁的,走的是快照读,上文已经阐明过了

记录锁本身不是锁定记录数据本身而是锁定索引记录,如果要锁的列没有索引,则会进行全表记录加锁

间隙锁(Gap Locks)

官方原文

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record. For example, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; prevents other transactions from inserting a value of 15 into column t.c1, whether or not there was already any such value in the column, because the gaps between all existing values in the range are locked.

比如 SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;

插入 c1 为 15 的记录会被锁定不可执行

这种默认存在于可重复读的事务隔离级别中的锁,锁定被圈定的范围不允许 insert,防止不可重复读,上文说了我们的事务隔离级别都是读已提交,默认会产生不可重复读的问题

InnoDB 锁的种类之临键锁和插入意向锁

临键锁(Next-Key Locks)

官方原文

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

这个锁本质是记录锁加上 gap 锁,数据库可重复读事务隔离级别默认存在

插入意向锁(Insert Intention Locks)

官方原文

An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.

插入意向锁是间隙锁的一种,专门针对 insert 操作,官方意思是说多个事务在同一个索引同一个范围区间插入记录时候,如果插入位置不冲突,不会彼此阻塞

隔离级别还是 RR

如何加表锁

MySQL常用引擎有 MyISAM 和 InnoDB,而 InnoDB 是 MySQL 默认的引擎。MyISAM 不支持行锁,而 InnoDB 支持行锁和表锁。

如何加锁?

隐式上锁(默认,自动加锁、自动释放)

MyISAM 在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此用户一般不需要直接用 LOCK TABLE; 命令给 MyISAM 表显式加锁。

-- 上读锁 --
SELECT -- 上写锁 --
INSERT, UPDATE, DELETE

显式上锁(手动)

上共享锁(读锁)的写法:lock in share mode,例如:

select  column_name from table_name where lock in share mode;

上排它锁(写锁)的写法:for update,例如:

select column_name from table_name where conditions for update;

解锁(手动)

-- 解锁所有锁表 --
UNLOCK TABLES;

假设我们要更新 teachers 表中,Linghu Chong 的邮箱为 linghu.chong@ninechapter.com,但是 teachers 表被上了读锁,请编写 SQL 语句,来实现更新 Linghu Chong 的邮箱。

-- 对 teachers 表上读锁 --
LOCK TABLES teachers READ;-- 解锁 --
UNLOCK TABLES;-- 更新邮箱 --
UPDATE teachers
SET email = 'linghu.chong@ninechapter.com'
WHERE name = 'Linghu Chong';

向 teachers 表中插入一条 Feng Qingyang 的信息,其邮箱为 feng.qingyang@163.com,其年龄为 37 岁,国籍为 CN,但是 teachers 表被上了读锁

LOCK TABLES teachers READ;

unlock TABLES;

INSERT INTO teachers(name,email,age,country)

value('Feng Qingyang','feng.qingyang@163.com',37,'CN')

查询 teachers 表中所有的信息,但是,courses 表被加了写锁

LOCK TABLES courses WRITE;

unlock TABLES;

select*

from teachers

如何加行锁

MySQL 存储引擎的发展是从 MyISAM 到 InnoDB,锁从表锁发展到行锁。行锁的出现从某种程序上是为了弥补表锁的不足。比如MyISAM 不支持事务,InnoDB 支持事务。

表锁虽然开销小,加锁快,但高并发下性能低。行锁偏向于 InnoDB 存储引擎,虽然开销大,加锁慢,锁定粒度小,会出现死锁,但高并发下性能更高。

事务和行锁都是在确保数据准确的基础上提升并发的处理能力。因此,InnoDB 存储引擎相比 MyISAM 而言,更适合高并发场景,同时支持事务处理。InnoDB 与 MyISAM 相比最大不同之处也在于这两点:支持事务、采用行级锁。

行锁是 MySQL 中粒度最细的一种锁机制,只对当前所操作的行进行加锁,行锁发生冲突的概率很低,其粒度最小,但加锁的代价最大。行锁有分为共享锁(S 锁)和排他锁(X 锁)。

InnoDB 的行锁是通过给索引项添加锁来实现的,这一点 MySQL 与 Oracle 不同,Oracle 是通过在数据库中对相应的数据行加锁来实现。InnoDB 行锁只有在通过索引条件检索数据时才能使用,否则会直接使用表级锁。需要注意的是行级锁一定要使用索引。

隐式上锁(默认,自动加锁、自动释放)

InnoDB 行锁的加锁的方式是自动加锁

  • 对于 UPDATE、DELETE、INSERT 操作,InnoDB 会自动给涉及数据集添加排他锁
  • 对于 SELECT 操作,InnoDB 不会添加任何锁

-- 不会上锁 --
SELECT
-- 上写锁 --
INSERT, UPDATE, DELETE

显示上锁(手动)

InnoDB 手工加锁方式

LOCK IN SHARE MODE 与 FOR UPDATE 只能在事务内其作用,以保证当前会话事务锁定的行不会被其他会话修改。

-- 读锁 --
SELECT *
FROM table_name
LOCK IN SHARE MODE;-- 写锁 --
SELECT *
FROM table_name
FOR UPDATE;

解锁(手动)

  1. 提交事务(commit)
  2. 回滚事务(rollback)
  3. 阻塞进程(kill)

请给 teachers' 表中编号为 3 的一行数据上一个读锁

select *

from teachers

where id=3

LOCK IN SHARE MODE;

【笔记】SQL 6-2相关推荐

  1. 2.SQL SERVER笔记——SQL SERVER系统概念

    2.SQL SERVER笔记--SQL SERVER系统概念 系统数据库 数据库管理员(DBA)的一项基本的技能是对SQL数据库引擎的系统数据库的深刻理解.数据库开发人员了解SQLSERVER自带的系 ...

  2. 天池大数据众智平台笔记SQL(一)

    本笔记为阿里云天池龙珠计划SQL训练营的学习内容,链接为:https://tianchi.aliyun.com/specials/promotion/aicampsql RDBMS(关系数据库管理系统 ...

  3. 《Web安全渗透全套教程(40集)》学习笔记 | SQL注入攻击及防御

    学习视频来源:B站<Web安全渗透全套教程(40集)> 个人在学习的同时,也验证了视频中的实验部分,现将授课笔记和实验笔记整理下来. SQL注入危害 SQL基础回顾 连接数据库 查看数据库 ...

  4. web安全学习笔记--sql语句(sql注入基础上)

    一.基础知和表内操作语法 1.sql语句对大小写不敏感!!! SELECT - 从数据库表中获取数据:select * from (columns/tables/databases); UPDATE ...

  5. 小菜鸡的学习笔记——sql注入之sqli-lab边学边练

    结合sqli-lab靶场的sql注入学习笔记<持续更新> 第一关 Way1:字符型联合注入 Way2:报错型注入 第二关:get数值型联合注入 第三关:字符型闭合注入 第四关:字符型闭合注 ...

  6. web漏洞“小迪安全课堂笔记”SQL注入

    文章目录 前言 SQL注入是什么? 注入原理 数据库结构 mysql数据库 参数类型 请求方法 如何判断注入点? 判断注入 1.信息收集 2.数据注入 3.高权限注入 魔术引号开关 跨库注入 获取所有 ...

  7. Web安全学习笔记——SQL注入

    一.MySQL注入 1. 常用信息查询 常用信息: 当前数据库名称:database() 当前用户:user() current_user() system_user() 当前数据库版本号:@@ver ...

  8. 笔记“SQL与Access”

    Transact-SQL语句进行导入导出:  1.         在SQL SERVER里查询access数据: -- ======================================= ...

  9. (Oracle学习笔记) sql语言

    文章目录 一.sql特点 二.sql语言分类 三.表空间 查询表空间 创建表空间 修改表空间名称 增加表空间大小 减小表空间大小 删除表空间 四.用户管理 查询用户 新建用户 修改用户口令 修改默认表 ...

  10. (Oracle学习笔记) sql*plus命令

    一.SET命令 显示系统时间,默认为off 显示sql语句执行耗时,默认为off 设置每页行数 查询一页设置的行数 设置不分页 设置一页空行数 查询一页空行数 设置查询结果是否滚动显示 格式化数值的默 ...

最新文章

  1. python学费多少-Python开发学费一般多少钱?
  2. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 简介 | 权限申请处理细节 | 添加依赖 | 界面权限申请结果处理 | 权限申请结果回调接口 )
  3. Bag-of-words model
  4. java 正方形字符串_java编程:怎么画一个正方形?
  5. druid ssh加密 java mysql_springboot 整合druid数据库密码加密功能的实现代码
  6. excel重复上一步快捷键_初学Excel办公软件重复上次的操作
  7. 二次封装dojo slider
  8. 你给客户报完价,客户就没消息了,什么原因呢?
  9. 基于CNN目标检测方法(RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN,YOLO,SSD)行人检测
  10. 2021牛客寒假算法基础集训营2,签到题FHIJ
  11. STM32驱动SPI FLASH(W25Q64)
  12. c语言 标准正态分布表,标准正态分布表ZP(Z).PDF
  13. slam入门2:轮式里程计与2D激光联合标定及里程计内参校准
  14. 如何提升客户的信任,实现与客户的连接,带动业绩的转变
  15. VVC/JEM代码学习26:m_pcTrQuant-transformN*N
  16. Y件DOOK: VSC 安装 谷歌浏览器调试 固件插件 Debugger for Chorme
  17. 腾讯地图javascript API实现地图模糊搜索标记,经纬度输入及点击双向定位
  18. c语言从键盘输入5阶方阵,输入5×5阶的矩阵,编程实现: (1)求两条对角线上的各元素之和....
  19. 【techQA】如何在Mac OS 11 Big Sur or M1芯片Mac下开启蓝牙Apt-X
  20. Android转换位图BUG,知其然不知其所以然

热门文章

  1. 计算机中 递归 的概念,递归是什么?关于递归的详细介绍
  2. 桥牌坐庄训练bm2000 level3闯关记录——A6
  3. Jenkins报Failed to remove prefix from file named
  4. Android 折叠屏技术发展与适配
  5. 【原创】迅驰2平台(Montevina)含义解释及其处理器参数规格一览(导购1)
  6. 老虎证券开放api期货合约建立
  7. 大叔也学Xamarin系列
  8. HDFS 概念之 block 详解
  9. QQ浏览器使用infinity新标签
  10. 实现两个矩阵相乘(Java)