1

来自 MySQL 文档:

锁定读取、UPDATE 或 DELETE 通常会在 SQL 语句处理过程中扫描的每个索引记录上设置记录锁。语句中是否存在将排除该行的 WHERE 条件并不重要。InnoDB 不记得确切的 WHERE 条件,而只知道扫描了哪些索引范围。

当我执行 UPDATE 时(虽然我也会对其他人感兴趣,现在我关心 UPDATE 语句),有没有办法将锁按相同的顺序放置,以便尽可能避免死锁?

如果在使用 INNER JOIN(或使用多个表)执行 UPDATE 时可以这样做,我也会非常感兴趣。

由于并发更新和插入(甚至删除),我的表中发生了死锁。

4

1 回答 1

1

您可以使用 select for update 语句锁定所有行:

start transaction;

--lock all needed data to be sure avoid deadlocks:
select 1 from table_1 where condition_1 for update;
select 1 from table_2 where condition_2 for update;
select 1 from table_3 where condition_3 for update;

--do updates
update in any order you want

--commit
commit;

mysql 死锁视频中,您可以看到第一部分用户如何引发死锁:

  1. 用户使用 2 个事务打开 2 个会话
  2. 用户t1在第一个会话中更新表,t2在第二个会话中更新表。
  3. 用户尝试扭曲更新:他t2在第一个会话和t1第二个会话上更新。
  4. 引发了死锁。

在第二部分,用户在更新之前选择更新并...(已删除;)

于 2015-12-09T15:23:50.387 回答