我试图掌握MySQL锁的概念,并在docs:https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html中看到本节:
锁定读取、更新或删除通常设置在SQL语句处理过程中扫描的每个索引记录上的记录锁。语句中是否存在排除行的条件并不重要。InnoDB不记得确切的位置条件,但只知道被扫描的索引范围。
这使我得出这样的结论:两个事务永远不能并行地锁定同一个表中的行。让我在下面的例子中解释一下:
假设我有下表:
CREATE TABLE t1 (id INT, PRIMARY KEY (id)) ENGINE = InnoDB;此外,假设我插入了7行。这是主键的平衡树:

现在假设我们用id 3锁定行:
SELECT * FROM t1 WHERE id=3 FOR UPDATE从上面的副翼
在处理SQL语句过程中扫描的每个索引记录上都有一个锁定读..。设置记录锁。
我猜想行3,5,10上有一个独占锁。是那么回事吗?
如果是这样的话,那么
SELECT * FROM t1 WHERE id=100 FOR UPDATE将尝试在行10上设置独占锁,因为它在进程中扫描以找到100。但这意味着,它必须等待另一笔交易完成。
这意味着,任何在表t1中锁定行的事务总是首先使用id 10锁定行。因此,两个事务不可能并行地锁定两个不同的行。
我的问题是:
发布于 2021-02-28 13:31:29
您的示例忘记了一条重要的信息,即同一行数据可以根据不同的标准进行多次索引。如果第二个索引与B树一起存在,并且假设索引是在id降序时排序的,那么您就可以同时访问值为100的行(这将是第二个索引的根节点)。
现在假设您不是指表行,而是指单个索引中的特定行位置。那么是的,上面的例子是正确的,当只在同一个索引中讨论时。
注意,这个答案有点高,只是为了解释问题上下文中的概念,我不能确切地说出MySQL在幕后还能做些什么。
https://dba.stackexchange.com/questions/286159
复制相似问题