首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >哪些记录被MySQL的“选择.用于更新”锁定

哪些记录被MySQL的“选择.用于更新”锁定
EN

Stack Overflow用户
提问于 2014-01-25 08:34:31
回答 1查看 88关注 0票数 0

我已经阅读并测试了MySQL的InnoDB中的行级锁,但我仍然很难说“我知道锁在MySQL中是如何工作的”!

以下是我的测试数据:

代码语言:javascript
运行
复制
mysql> select * from lockable;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
|  1 | A  | A  |
|  2 | A  | B  |
|  3 | A  | C  |
|  4 | B  | A  |
|  5 | B  | B  |
|  6 | B  | C  |
|  7 | C  | A  |
|  8 | C  | B  |
|  9 | C  | C  |
+----+----+----+
9 rows in set (0.00 sec)

为了测试MySQL在行级锁方面的行为,我打开了两个终端并连接到MySQL。我要给他们取名为mysql1>mysql2>。下面是我在第一个终端上执行的内容:

代码语言:javascript
运行
复制
mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable WHERE c1 = "A" FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
|  1 | A  | A  |
|  2 | A  | B  |
|  3 | A  | C  |
+----+----+----+
3 rows in set (0.00 sec)

然后在第二个航站楼:

代码语言:javascript
运行
复制
mysql2> SELECT * FROM lockable WHERE c1 = "B" FOR UPDATE;

令我惊讶的是,上面的查询将被第一个查询阻塞!于是我回到了第一个航站楼,重新开始:

代码语言:javascript
运行
复制
mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable LIMIT 3 FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
|  1 | A  | A  |
|  2 | A  | B  |
|  3 | A  | C  |
+----+----+----+
3 rows in set (0.00 sec)

然后在第二个航站楼:

代码语言:javascript
运行
复制
mysql2> SELECT * FROM lockable WHERE LIMIT 6,1  FOR UPDATE;

第二个终端再次被第一个终端阻塞!是否存在并非所有表的记录都被锁定的情况?如果不是,为什么这被称为“行级锁定”?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-25 09:42:10

我的问题的答案在MySQL手册里说过

锁定读取、更新或删除通常设置在SQL语句处理过程中扫描的每个索引记录上的记录锁。

因此,锁被应用于在遍历过程中被扫描的记录,而不是所有的记录。如果没有找到索引,则会进行全面扫描,并锁定所有记录。因此,我需要在列上设置一个索引。即使这样,如果在访问目标记录时读取了一些记录,那么它们也会被锁定(即使它们可能没有最终被选中)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21348410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档