在 MySQL 中,为什么在使用未提交读时从 select 设置变量会获取锁?

2023-12-20

我们在 MySQL 中有一个使用 InnoDB 的表,并且我们使用未提交读的事务隔离级别。为什么设置@x如图所示获取锁?

mysql> set @x = (select userID from users limit 1);
Query OK, 0 rows affected (0.02 sec)

mysql>

尝试从另一个提示更新此表会导致超时错误:

mysql> update users set userID = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

就其价值而言,这种锁定不仅限于READ-UNCOMMITTED:

mysql1> show variables like '%isolation%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
mysql1> BEGIN;
mysql1> SET @x := (SELECT x FROM foo LIMIT 1);

mysql2> UPDATE foo SET x = x+1;
[gets a lock wait]

mysql3> SHOW ENGINE INNODB STATUS;
...
---TRANSACTION 228746, ACTIVE 22 sec
2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 58, OS thread handle 0x7fc262a1c700, query id 8163
  192.168.56.1 root cleaning up
TABLE LOCK table `test`.`foo` trx id 228746 lock mode IS
RECORD LOCKS space id 801 page no 3 n bits 80 index `PRIMARY` 
  of table `test`.`foo` trx id 228746 lock mode S
...

正如您记录的错误中所讨论的,Bug #67452 使用未提交读时,从 select 设置变量会获取锁 http://bugs.mysql.com/bug.php?id=67452,这种行为可能是设计使然。它似乎属于同一类别SELECT其结果用于修改数据的语句,如所描述的这些情况:

http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html

当在构造中使用 SELECT 时REPLACE INTO t SELECT ... FROM s WHERE ... or UPDATE t ... WHERE col IN (SELECT ... FROM s ...), InnoDB 对表中的行设置共享下一键锁s.

下一键锁的原因是为了使SELECT结果更稳定。也就是说,我们不希望匹配的行SELECT在使用它们时进行更改UPDATE或其他数据修改语句。

即使 tx_isolation 是REPEATABLE-READ,这很重要,因为 InnoDB 不支持REPEATABLE-READ for SELECT当语句作为任何类型的一部分执行时UPDATE.


回复您的评论:

无论文档如何,都会发生以下情况:

当你做简单的事时SELECT语句中,InnoDB 不会锁定任何东西,在任何事务隔离中除外SERIALIZABLE.

如果你做一个SELECT ... LOCK IN SHARE MODE or SELECT ... FOR UPDATE,当然会锁定。

但当你这样做时SELECT作为数据修改语句的一部分,例如INSERT INTO...SELECT或者在一个子查询中UPDATE或者正如您在SET @variable := (SELECT...),它使用共享锁来确保更新过程中数据不会更改。

文档可能不完整。最好测试一下。

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

在 MySQL 中,为什么在使用未提交读时从 select 设置变量会获取锁? 的相关文章

随机推荐

  • 匹配可变参数非类型模板

    假设我有两个结构 Foo and Bar template
  • 是否有任何不明显的滥用 GUID 的方式?

    GUID 通常用于唯一地标识各种实体 来自外部系统 文件等的请求 像魔术一样工作 您调用 GiveMeGuid Windows 上的 UuidCreate 函数 一个全新的 GUID 随时为您服务 鉴于我的代码每次需要新的 GUID 时都会
  • 如果有 css3 skew 的 ie 过滤器是什么?

    我现在有 moz transform rotate 45deg skewX 45deg ms transform rotate 45deg skew 45deg 0deg webkit transform rotate 45deg skew
  • Material ui 根据所选主题模式使用调色板原色

    在使用 mui React 时 我想使用主题主调色板中的颜色为使用 div 制作的一些非材质 ui 自定义组件着色 我目前可以使用theme palette primary main or the light直接颜色 包括theme pal
  • 在奇怪的情况下抛出 AccessViolationException

    我使用 c 已经很长时间了 但从来没有遇到过这种错误 首先 你是否发现这个代码块有什么问题 可能是错误的 当然 除了它的逻辑 我知道它总是返回 0 public static int GetDecimals MySimpleEnum val
  • 在 Oracle 中找不到表 v$parameter

    我想使用 SQL 查询获取 Oracle 中的会话数 SELECT value FROM v parameter WHERE name sessions 但我收到这个错误 Error starting at line 1 in comman
  • Android 密码编辑文本显示文本

    我用过一个Edittext有属性android inputType textPassword 但是 当我在其中输入一些文本时 文本在变为实心项目符号之前会逐字符可见 当用户输入文本时 如何使文本不可见 请帮我 尝试添加EditText属性
  • Java Swing GUI 沙漏

    有一个JTabbedPane In my Swing程序 当用户单击选项卡时 程序需要一段时间来获取数据并处理结果 然后在所选选项卡中显示结果 如何显示沙漏或类似效果的东西让用户知道它正在处理数据 在完成工作之前不要再次单击该选项卡 最简单
  • java中的管道I/O流

    我无法理解 java 中管道 I O 流的用途 如果我使用输出流写一些东西 我无论如何都可以使用输入流再次读取它 那么管道流需要什么 Pipes in Java IO提供在同一 JVM 中运行的两个线程进行通信的能力 因此 管道是数据的常见
  • 来自数据库的 Symfony2 路由规则 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • ConnectivityManager.CONNECTIVITY_ACTION 在 API >= 14 中断开网络连接?

    我需要获取与哪个设备断开连接的网络 现在我用 NetworkInfo ni intent getParcelableExtra ConnectivityManager EXTRA NETWORK INFO 并检查 ni isConnecte
  • SpriteKit:在播放之前将声音文件预加载到内存中?

    只是想知道这是否可能 目前 我第一次在应用程序运行时播放声音文件时 在声音实际播放之前有明显的延迟 就像它正在缓存它或其他什么 此后 它会立即播放 没有问题 但如果我完全关闭应用程序并重新启动它 第一次播放声音时延迟将恢复 这是我用来播放声
  • 如何在 AngularJS 部分中保留新行?

    在 AngularJS 部分中 我循环访问条目列表 如下所示 ul class entries li strong entry title strong p entry content p li ul 内容为 entry content 有
  • 如何使用 bash 复制每行中的字符串?

    我有一个文本文件 每一行都包含字符串 如下所示 abc dog zebra 我想让它像 abc abc dog dog zebra zebra 在 bash 中如何最好地做到这一点 你可以打电话sed sed r s 1 1 dupcol
  • 在命令行上使用 Firefox 截取整页屏幕截图

    我在 VPS 中的 Xvfb 上运行 Firefox 我想做的是对页面进行全屏截图 我可以使用以下命令将 Firefox 重定向到特定页面 firefox http google com 并使用 ImageMagick 截取屏幕截图 X 内
  • 如何调试为什么最简单的 MySQL 查询返回 false?

    我和 xampp 一起工作 我执行MySQL连接 connection mysql connect host user passw mysql select db db connection 我收到了 echo 命令的输出 通过检查布尔返回
  • Miniprofiler.Current 方法不返回时间

    我正在尝试使用此代码来获得时间MiniProfiler var profiler StackExchange Profiling MiniProfiler Current 但它返回0 ms结果 如何获得current time在迷你分析器中
  • 如何搜索 Perforce 仓库 (P4V) 中的文件内容?

    我目前使用 Perforce 版本 2010 2 该版本似乎没有集成的搜索功能来遍历每个文件的内容 我当前的 P4V 版本仅允许我搜索文件名 但不能搜索内容 对此的任何意见将不胜感激 先感谢您 我相信 尝试 2010 1 版本中添加的 p4
  • 尾部斜杠和首字母 www

    我有这个 htaccess RewriteEngine On redirect with www RewriteCond HTTP HOST mydomain NC RewriteRule http www HTTP HOST 1 R 30
  • 在 MySQL 中,为什么在使用未提交读时从 select 设置变量会获取锁?

    我们在 MySQL 中有一个使用 InnoDB 的表 并且我们使用未提交读的事务隔离级别 为什么设置 x如图所示获取锁 mysql gt set x select userID from users limit 1 Query OK 0 r