【发布时间】:2015-12-09 08:35:24
【问题描述】:
来自 MySQL 文档:
锁定读取、UPDATE 或 DELETE 通常会在 SQL 语句处理过程中扫描的每条索引记录上设置记录锁。语句中是否存在将排除该行的 WHERE 条件并不重要。 InnoDB 不记得确切的 WHERE 条件,而只知道扫描了哪些索引范围。
当我执行 UPDATE 时(虽然我也会对其他人感兴趣,但现在我关心的是 UPDATE 语句),有没有办法以相同的顺序放置锁,从而尽可能避免死锁尽可能?
如果在使用 INNER JOIN(或多个表)执行 UPDATE 时可以这样做,我也会非常感兴趣。
注意由于并发更新和插入(甚至删除),我的表中发生了死锁。
【问题讨论】:
-
@danihp 表锁如果我理解正确会导致瓶颈。我正在搜索有序行锁定。
-
另外,你可以先select ... for update所有你需要的数据。请记住将其包含在单个事务中。
-
@danihp 是的,但是在那种情况下,如果我理解正确的话,我会失去性能,因为我会一一进行更新,或者如果执行相同的更新,我认为扫描索引将是相同的,无论这些行是否被锁定。我说的对吗?
-
如果 Viktor Söderqvist 的评论是正确的。您可以首先将要更新的所有数据分组在一行中:
SELECT 1 FROM sometable WHERE somecondition GROUP BY 1 FOR UPDATE;(对同一事务中的其他相关数据重复)然后进行更新。 (注意,没有 select for update 子句)