我需要完成以下工作:
我需要在同一个表中插入两行,要么都插入,要么都不插入(原子插入两行)。
我使用 InnoDB 表上的事务来执行此操作,如下所示:
$db->beginTransaction();
# Using PDO prepared statments, execute the following queries:
INSERT INTO t1 set uid=42, foo=1
INSERT INTO t1 set uid=42, foo=2
$db->commit();
但是,如果表中没有列的值为“42”的行,我也只希望插入这些行。
所以我这样做:
$stmt = $db->prepare("SELECT id FROM t1 WHERE uid != ?");
$stmt->execute(array(42));
if($stmt->fetchColumn() < 0){
# There is no row with uid=42, so
# perform insertions here as per above.
INSERT INTO t1 set uid=42, foo=1
INSERT INTO t1 set uid=42, foo=2
}
但是这里存在竞争条件,因为可以在检查该行之后和插入新行之前立即插入 uid=42 的行。
我应该如何解决这个问题?
我可以锁定表,然后在表锁内执行 InnoDB 事务吗?
我可以在事务内部进行选择以检查 uid=42 的现有行吗?那是没有比赛条件的吗?