【发布时间】:2014-05-15 11:21:51
【问题描述】:
我想在非主键字段中插入具有唯一值的行。我不能使用唯一索引(因为多字段索引中的NULL值,但在这里并不重要)。
我使用 INSERT/SELECT WHERE NOT EXISTS 作为原子(我希望)操作 - 见下文。
我将用简化的例子来描述问题:
我有一张空桌子:
CREATE TABLE Test (
Id int(11) NOT NULL AUTO_INCREMENT,
A int(11) DEFAULT NULL,
PRIMARY KEY (Id)
) ENGINE=InnoDB;
...和 2 个自动提交模式关闭的会话:
在第一次会话中我执行:
INSERT INTO Test (A)
SELECT A FROM (SELECT 1 AS A) Inn
WHERE NOT EXISTS (SELECT A FROM Test WHERE A = 1 FOR UPDATE);
在第二个会话中我执行:
INSERT INTO Test (A)
SELECT A FROM (SELECT 2 AS A) Inn
WHERE NOT EXISTS (SELECT A FROM Test WHERE A = 2 FOR UPDATE);
如您所见,我正在插入独立值。但是第二个会话被第一个会话锁定。为什么?可能是因为gap/next-key lock。
我怎样才能插入“手动”避免重复键且没有相互锁定的记录?
默认事务隔离级别是 REPEATABLE READ,我不想更改数据库的默认设置,因为其他应用程序使用它。
【问题讨论】:
-
这似乎是一种相当复杂的 INSERT IGNORE 方法。您采用这种方法的原因是什么?
-
因为我可以在某些唯一索引列中有 NULL。你知道我还能如何插入唯一值吗?