16

如果我有这个多重更新查询

UPDATE user u
INNER JOIN user_profile up ON up.user_id = u.id
SET u.name = 'same_name_i_already_had', up.profile.age = 25
WHERE u.id = 10

假设 user 表中的第 10 行已经有名称“same_name_i_already_had”,所以它不应该被更新。

另一方面,user_profile 表中的行有不同的年龄,所以 MySQL 应该更新它。

假设MySQL作为 RDBMS 和InnoDB,其行级锁定系统作为两个表的引擎,

尽管不必更新该行的 name 字段,MySQL 是否会锁定用户表中的行?

4

2 回答 2

13

它确实将行锁定在user. 您可以使用出色的innotop工具 来验证这一点。

  • 运行 innotop 并按“L”键以显示 InnoDB 锁屏幕。
  • 打开另一个会话,登录 MySQL 并开始交易。
  • 执行您显示的更新,但不要提交。
  • 在 innotop 屏幕中查看锁。

例如,我在运行 MySQL 5.5 的测试 VM 上创建了表 user 和 user_profile,并执行了上面列出的步骤。这是输出:

[RO] Locks (? for help) localhost, 08:34.568, InnoDB 10s :-), 0.10 QPS, 2/0/0 con/run/cac thds, 5.5.

__________________________________________ InnoDB Locks __________________________________________
ID  Type    Waiting  Wait   Active  Mode  DB    Table         Index    Ins Intent  Special        
 2  TABLE         0  00:00   02:35  IX    test  user                            0                 
 2  RECORD        0  00:00   02:35  X     test  user          PRIMARY           0  rec but not gap
 2  TABLE         0  00:00   02:35  IX    test  user_profile                    0                 
 2  RECORD        0  00:00   02:35  X     test  user_profile  PRIMARY           0  rec but not gap
于 2011-06-29T18:46:38.717 回答
4

几乎可以肯定它无论如何都会锁定行。我不知道有任何简单的字段首先检查更改。锁定、写入和解锁更容易、更快捷。如果在锁定之前进行了检查,那么就会存在竞争条件:锁定完全避免的事情。

于 2011-06-29T18:35:33.483 回答