这似乎是一个常见问题,但是我发现矛盾的答案。
假设我有一个InnoDB表Table A
,其中包含列A
和B
。在(A, B)
上有一个复合索引,在(A, B)
上有一个唯一约束。
在事务中,如果我执行SELECT FOR UPDATE来检索(A, B)
的某行而没有找到行,则并发事务可以将相同的(A, B)
插入TableA
,或者我的SELECT FOR UPDATE获得了INTENTION EXCLUSIVE LOCK之后,并发事务是否被阻止?这是针对隔离级别“ READ COMMITTED”的。
在文档中:
锁定读取,UPDATE或DELETE通常会对在处理SQL语句时扫描的每个索引记录设置记录锁定。
...
对于具有唯一搜索条件的唯一索引,InnoDB仅锁定找到的索引记录,而不锁定其前的空白。
— https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html
这似乎意味着SELECT FOR UPDATE(如果像UPDATE一样操作)将获得对索引记录(A, B)
的意图排他锁,这意味着另一个事务将无法插入。
Stackoverflow帖子与我达成共识: -https://stackoverflow.com/a/17069317/1336653
Stackoverflow发布与我不同意: -https://stackoverflow.com/a/37770594/1336653 -https://stackoverflow.com/a/31184293/1336653 -https://stackoverflow.com/a/21263608/1336653(至少在我的隔离级别上如此)
如果一致认为SELECT FOR UPDATE不能在不存在的行上获得锁,那么INSERT ... ON DUPLICATE KEY是唯一的解决方案吗?