【问题标题】:Putting an order in the way how locks are aquired in MySQL确定如何在 MySQL 中获取锁
【发布时间】:2015-12-09 08:35:24
【问题描述】:

来自 MySQL 文档:

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

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

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

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

【问题讨论】:

标签: mysql database mysql-5.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 deadlock video 中,您可以看到第一部分用户如何引发死锁:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多