InnoDB 数据库锁 (REPEATABLE-READ)

本贴最后更新于 3165 天前,其中的信息可能已经时移世改

###InnoDB 加锁方式(REPEATABLE-READ)

共享锁:允许事物读取数据,阻止其它事物获取该数据集的排他锁 排他锁:允许获取锁的事物更新数据集,阻止其它事物获取数据集的共享 锁和排他锁。

根据锁定数据集的大小,mysql 的排他分为表锁和行锁

  1. 表锁,锁定整个表
  2. 行锁,锁定一个数据子集

在 InnoDB,行锁是通过给索引上的索引项加锁来实现的,也就是说,只有通过索引条件检索数据,才能使用行锁,否则会使用表锁。


表锁:
无索引

session1 session2
set autocommit = false
update lock_test set fkey = 'A' where c = 1
Rows matched: 2 Changed: 2 Warnings: 0
update lock_test set fkey = 'C' where c = 2
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

行锁:

  • 对字段 c 加普通索引
session1 session2
set autocommit = false
update lock_test set fkey = 'A' where c = 1
Rows matched: 2 Changed: 2 Warnings: 0
update lock_test set fkey = 'C' where c = 2
Rows matched: 2 Changed: 2 Warnings: 0

使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。


  • 对字段 C 加普通索引
session1 session2
set autocommit = false
update lock_test set fkey = 'A' where c = 1 and fkey = 'D'
Rows matched: 1 Changed: 1 Warnings: 0
update lock_test set fkey = 'C' where c = 2 and fkey = 'M'
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

InnoDB 对索引项加锁,尽管更新两条不同的数据,但使用相同的索引项


注意:

  • 不是使用了索引字段过滤就会使用行级锁,需要 explain 看下 mysql 具体的执行计划
  • InnoDB 行级锁是对索引项加锁,即
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 UPDATE lock_test NULL range idx_lock idx_lock 8 const 2 100.00 Using where; Using temporary

rows 对应的数据写操作均会被锁定

###间隙锁

  • 当使用范围查询时,InnoDB 不仅会对存在的数据加锁,也会对不存在的空隙加锁,即间隙锁(max(id)=10 | where id > 9 | 对 10 加锁 | 对 >10 空隙加锁)

  • 这种加锁的目的是为了防止幻读, 防治写操作过程中出现其它 session 提交了 id > 10 的数据。

间隙锁:

  • 对不存在的索引间隙添加锁,阻止对该间隙的修改.
session1 session2
set autocommit = false
update lock_test set fkey = 'A' where c < 6
Rows matched: 1 Changed: 1 Warnings: 0
insert into lock_test(c, fkey) values (2, 'T');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
session1 session2
set autocommit = false
update lock_test set fkey = 'A' where c < 6
Rows matched: 1 Changed: 1 Warnings: 0
update lock_test set fkey = 'A' where id = 2; 注释:存在一条 id = 2 and c = 3 的数据
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
session1 session2
set autocommit = false
update lock_test set fkey = 'A' where c < 6
Rows matched: 1 Changed: 1 Warnings: 0
insert into lock_test(c, fkey) values (7, 'CA');
Rows matched: 1 Changed: 1 Warnings: 0
  • 当 update 过滤条件为范围查询并且使用普通索引时,会对普通索引不存在部分添加间隙锁,主键索引数据添加排他锁。
  • 当 update 过滤条件为范围查询并且使用主键索引时,会对主键索引添加间隙锁。
  • 当执行 insert 时,会同时对普通索引以及主键添加间隙锁

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3200 引用 • 8216 回帖
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    345 引用 • 747 回帖 • 1 关注
  • 索引
    24 引用 • 28 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • meikaiyipian

    沙发
    多谢楼主分享,mark 一下
    @V 前排带上小薇

  • V

    嘘....我正在思考人生

  • sweat89

    学习学习···

  • 88250

    表格好迷幻

    1 回复
  • eddy 1
    作者

    主要是想模拟两个会话不同的执行顺序

推荐标签 标签

  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9713 引用 • 44202 回帖 • 90 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    150 引用 • 257 回帖 • 1 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4601 回帖 • 708 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    290 引用 • 4494 回帖 • 653 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • abitmean

    有点意思就行了

    37 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    133 引用 • 1124 回帖 • 111 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    84 引用 • 324 回帖
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    181 引用 • 400 回帖
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 181 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 1 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖
  • 招聘

    哪里都缺人,哪里都不缺人。

    188 引用 • 1057 回帖
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 741 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    58 引用 • 25 回帖 • 2 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 177 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    162 引用 • 1082 回帖
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 20 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    245 引用 • 1338 回帖 • 1 关注
  • OneNote
    1 引用 • 3 回帖
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 4 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    125 引用 • 74 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 167 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    286 引用 • 248 回帖