MySQL 通过在非索引列上执行删除语句时锁定整个表来尝试防止什么现象

2024-04-09

使用可重复读的 MySQL 隔离级别。

给定表test具有非索引列quantity:

id    |     quantity
--------------------
1     |      10
2     |      20
3     |      30

Tx1执行第一个,注意它还没有提交,这意味着所有获取的锁还没有释放。

Tx1:

START TRANSACTION;
DELETE FROM test WHERE quantity=10;

现在执行Tx2

Tx2:

START TRANSACTION;
INSERT INTO test(quantity) VALUES (40);
COMMIT;

对于 Tx2,我得到以下结果:

Lock wait timeout exceeded; try restarting transaction

我理解,作为quantity列没有索引,delete语句进行全表扫描,锁定所有行(无关紧要where条件匹配或不匹配),并且还在聚集索引中的每个索引记录之前和之后应用间隙锁,从而导致表完全阻塞insert来自 tx2 的语句无法获取要插入的行的锁。

来自 MySQLmanual https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html(对于可重复读隔离级别):

  • 对于具有唯一搜索条件的唯一索引,InnoDB 仅锁定找到的索引记录,而不锁定其之前的间隙。

  • 对于其他搜索条件,InnoDB 会锁定扫描的索引范围,使用间隙锁或下一个键锁来阻止其他会话插入该范围所覆盖的间隙(这在我的例子中使用)。

考虑到任何给定隔离级别中的锁定都用于防止phenomenas我有点困惑在这种情况下阻止整个表的原因是什么,我的意思是什么样的phenomena在这种情况下可以阻止整个表的阻塞吗?


默认情况下,InnoDB 使用一致快照Repeatable Read https://vladmihalcea.com/non-repeatable-read/隔离级别,这意味着您可以获得元组和范围的可重复读取。

即使 SQL 标准这么说Phantom Reads https://vladmihalcea.com/phantom-read/被阻止Serializable然后Repeatable Read可能无法阻止它。

有关间隙锁定如何工作的更多详细信息,请查看这篇文章由 Percona 撰写 https://www.percona.com/blog/2012/08/28/differences-between-read-committed-and-repeatable-read-transaction-isolation-levels/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL 通过在非索引列上执行删除语句时锁定整个表来尝试防止什么现象 的相关文章

随机推荐

  • numpy正半定警告

    在我正在编写的Python脚本中 我正在使用表达式模拟多元正态随机向量 np random multivariate normal np zeros dim obs y cov 我的脚本运行 但生成以下警告 RuntimeWarning c
  • html5/jquery后退按钮

    是否有一个库或一段代码可以使特定按钮充当正确的浏览器后退按钮 它将带您到之前加载的上一个页面 目前我只是指定href我假设的是之前加载的页面 但得出的结论是这不起作用 因为可以从不同的屏幕访问一个屏幕 是否有这样的示例 或者我是否需要创建自
  • Android:从另一个片段打开一个片段

    我是 Android 新手 这是我的第二个应用程序 我正在创建一个选项卡式活动 其中第一个片段具有用于创建新任务的表单 第二个片段具有所有已保存任务的列表 第三个片段将在从第二个片段的列表中选择时显示对任务的评论分段 第三个片段也应该像一个
  • 如何将 WSGI 中的首选编码设置为 UTF-8

    感觉这里有点疯狂 我已经使用 mod wsgi 设置了 Apache 但我无法使编码正常工作 我有 测试 mod wsgi 是否在守护进程模式下运行 read 格雷厄姆 邓普尔顿的博客文章 http blog dscpl com au 20
  • ReportLab 表的列跨越 PDF 页面上的所有行?

    我正在尝试按以下格式在 reportLab 中布局表格 该表是动态的并且可以有很多行 a b a a tTableStyle SPAN 1 0 1 1 如果表格适合一页 则工作正常 但如果表格分为几页 则崩溃 如果没有跨度 表格可以正常分割
  • 带有时态表的 Entity Framework Core 3.1 - 访问 SysStartTime 和 SysEndTime

    我已经基于 Microsoft SQL 文档创建了时态表使用默认历史表创建临时表 https learn microsoft com en us sql relational databases tables creating a syst
  • 将 Pylons 控制器作为单独的应用程序运行?

    我有一个 Pylons 应用程序 我想将一些逻辑移动到单独的批处理过程中 我一直在主应用程序下运行它进行测试 但它将在数据库中执行大量工作 我希望它是一个单独的进程 将在后台不断运行 主 pylons 应用程序会将作业提交到数据库中 新进程
  • 如何在 android 中构建支持旧 SDK 版本 (minSdkVersion) 的应用程序

    当通过向导创建新项目并给出错误时 那就太沮丧了 我只是使用 MinSdk 9 创建新项目以使应用程序在姜饼上运行 这给了我以下错误 Error Execution failed for task app processDebugManife
  • 如何让 Discord 机器人异步等待多条消息的反应?

    tl dr 我的机器人如何异步等待多条消息的反应 我正在向我的 Discord 机器人添加石头剪刀布 rps 命令 用户可以通过输入调用命令 rps以及一个可选参数 指定要玩的用户 rps TrebledJ 被调用时 机器人将直接向调用它的
  • nextjs 动态路由渲染内容不起作用

    我被这个问题困扰了很多天 我在用Next js https nextjs org 并有 3 页 页面 index js 页面 categories js 页面 类别 slug js The categories slug js正在使用Nex
  • 从 Hudson 运行 DUnit 测试

    我终于让 Hudson 构建了我的项目和相应的测试项目 使用 Embarcadero 论坛中提供的 XMLTestRunner2 单元 手动正确运行测试可执行文件会生成包含测试结果的 dunit report xml 文件 但我无法让 Hu
  • HashSet.contains 在不应该返回 false 时返回 false

    我有这个代码 public class Tray private Set
  • 将 Java 集合转换为 Scala 集合

    与堆栈溢出问题相关Scala 相当于 new HashSet Collection https stackoverflow com questions 674545 如何转换 Java 集合 java util List比如说 到 Scal
  • XSLT 身份转换

    我正在测试 XSLT 身份转换 因此我随机选择了 www w3schools com 上的以下示例 因为它允许我在线尝试 我将右侧窗格中的 XSLT 更改为身份转换
  • 毕加索库,Android:使用错误侦听器

    我正在使用毕加索库来加载图像 但遇到了一个问题 当图像加载失败时 我想隐藏视图而不是加载默认图像 我从源代码中注意到 添加侦听器的唯一方法似乎是来自构建器 但是当图像加载失败时 永远不会调用错误方法 有人对此有经验吗 iv ImageVie
  • Android imageview 从缩放图像中获取像素颜色

    我的家庭自动化应用程序有一个功能 人们可以将图像上传到手机 其中包含平面图和仪表板 他们可以使用它们来控制家庭自动化软件 我让他们上传两张图像 一张可见图像 其中包含他们想要显示的图形 第二张彩色图 其纯色对应于他们想要从可见图像中定位的区
  • 在opengl中,如何获得像素和gl.gltranslatef(floatx,y,z)之间的关系?

    我正在尝试在 Android 上学习 opengl 的东西 在 gl gltranslatef x y z 调用中 我将纹理沿 ve x 方向移动一些单位 但我无法找到 1 个 x 单位所属的像素数 这是我正在做的事情 我调用 gl glv
  • Simba Athena ODBC:无法使用 SQLGetPrivateProfileString 函数

    这很奇怪 我想设置从 RStudio 到我在 AWS Athena 中的实例的连接 我在用unixodbc作为驱动程序管理器 并通过使用测试连接成功isql v Simba Athena 但是 当我在 RStudio 中测试连接时 con
  • deviceready 事件未在 Angular 混合应用程序中触发

    我正在构建一个全平台 Angular 6 应用程序 该应用程序将用 Cordova 8 1 2 包装 不幸的是我无法制作设备就绪触发事件 我有两个独立的项目 一个用于 Angular 一个用于 Cordova 我可以使用以下命令构建 Ang
  • MySQL 通过在非索引列上执行删除语句时锁定整个表来尝试防止什么现象

    使用可重复读的 MySQL 隔离级别 给定表test具有非索引列quantity id quantity 1 10 2 20 3 30 Tx1执行第一个 注意它还没有提交 这意味着所有获取的锁还没有释放 Tx1 START TRANSACT