同時クエリが混乱するのを防ぐためにクエリを作成しています。 私はかなり良い方法があると確信しています。それが私がここにいる理由です。INSERTステートメントで複数のSELECTを使用して競合状態を防止する
基本的には、テーブルの列は次のようになります。最後の場合
- :私はここに、新しい行を挿入すると
id : INT(10) unsigned auto_incremented number : INT(6) unsigned zerofill date : DATETIME
私はその数値を設定する必要があるかであります挿入された行のの日付は今日、の番号 =最後に挿入された行の番号+1
- E最後に挿入された行の日付は昨日であるかの前に、私が最初に考えた後、数 = 1
最後の行の日付と番号を選択し、私の挿入を行い、その後、PHPを使用して、新しい番号を設定します。
$pdo->beginTransaction();
$stmt = $pdo->prepare("SELECT `number`, `date` FROM `table` ORDER BY `id` DESC LIMIT 1");
$stmt->execute();
$infos = $stmt->fetch(PDO::FETCH_ASSOC);
$date = date("Y-m-d H:i:s");
if (date("Ymd", strtotime($infos['date'])) < date("Ymd", strtotime($date))) {
$number = 1;
} else {
$number = $infos['number'] + 1;
}
$stmt2 = $pdo->prepare("INSERT INTO `table` (`number`, `date`) VALUES (:number, :date)");
$stmt2->execute(array(":number" => $number, ":date" => $date));
$pdo->commit();
別のスレッドが同じ番号を選択して、それと同じ番号を挿入しようとするのを防ぐのに十分なトランザクションはありますか?
親愛なる友人のGoogleとSOを使っても、私は自分自身でその質問に答えることができなかったので、「私はMySQLですべての作業を行うことはできないのですか?次のクエリを出しました:
INSERT INTO `table`(`number`, `date`)
SELECT IF(
DATE((SELECT `date` FROM `table` ORDER BY `id` DESC LIMIT 1)) < CURDATE(),
'1',
(SELECT `number` + 1 FROM `table` ORDER BY `id` DESC LIMIT 1)
), NOW()
これは良い方法ですか?
何かをする前にテーブルをロックするだけでいいですか?
私はこれがどのように行われるべきか見るにはあまりにも愚かですか?
日付をインクリメントする順番で番号を挿入しようとしていると判断した場合、日付と番号の列に複合一意索引を作成し、2つの並行クエリが実行されている同じ日に同じ番号を入力してください。 –
さて、それは単なるメモでした。私はトランザクションが他のトランザクション状態に依存しているとは思わない。一度に30人のユーザーが読み込まれた場合は、30人のユーザーが最初に終了する29個のトランザクションすべてを必要とします。私はあなたが時間を通過することを許可している 'update'を'選択 'しないで、一気にそれを行います。 – chris85
トランザクションでは同じ番号を選択するのに十分ではありませんが、キーが一意の場合は2番目の挿入が失敗し、トランザクションを取り消してからもう一度やり直すことができます。 – awiebe