私は以下を達成する必要があります:
同じテーブルに 2 つの行を挿入する必要があり、両方が挿入されるか、どちらも挿入されません (2 行を原子的に挿入します)。
次のように 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 トランザクションを実行できますか?
トランザクション内で select を実行して、uid=42 の既存の行をチェックできますか? それはレースコンディションフリーですか?