質問: $pdo->prepare( $sql ); $prepare->bindValue( 1, "yamada" ); $prepare->bindValue( 2, 11 ); $prepare->bindValue( 3, 22 ); $prepare->execute(); $pdo->commit(); } catch ( PDOException $e ) { //すでに新規追加が動いていれば下記のechoを出力 $dbh->rollBack(); echo "エラー出力"; } ``` 追加は基本的に問題なくされますが、Aがアクセスしてから5秒後にBがアクセスしても、2つとも新規で追加されてしまいます。 これをAのみ追加され、BはDBを参照はできるが、追加はされず、DB内のデータと”エラー出力"とだけ出るようにしたいです。 なにか根本的に間違えているのでしょうか? またもう一つききたいのですが、 $pdo->commit(); これで一時的にためていたものをDBに追加する。と書いていたのですが、これを外した場合も、問題なく追加されます。 なぜなのかご教授いただけると幸いです。 よろしくお願いいたします! 追記 ikedasさん ご返答ありがとうございます。 指定頂いたページは一通り目を通しておりました・・・ただ理解力がないため、出来ませんでした。 データベースはMySQL 5.6.36です。 Kosuke_Shibuyaさん ご返答ありがとうございます。 たとえば、1時間に一度、自分の他のサイトを見に行き、データを取ってきて、それをDBに格納する。という処理を考えております。 そのため、AとBがほぼ同時に来た場合、ロックを掛けておかないと取得している時に、Bも同じものを取得してきて、同じモノが2度登録されてしまうのでは無いかと考えておりました。 別の方法でも、なにかいい方法があればご教授頂けると幸いです。
回答: > > たとえば、1時間に一度、自分の他のサイトを見に行き、データを取ってきて、それをDBに格納する。という処理を考えております。 > > そのため、AとBがほぼ同時に来た場合、ロックを掛けておかないと取得している時に、Bも同じものを取得してきて、同じモノが2度登録されてしまうのでは無いかと考えておりました。 > > > 「同じもの」ということですが、逆に言えば、データベースのテーブルに格納されたデータは区別できる、ということですね。データのどこで区別するのでしょうか。 仮に、URLで区別するのだとします。であれば、url列に一意のインデクス (キー) を付けてやれば、すでにテーブル中にある行のURLと同じURLを含んだ行を追加することはできません (あとから追加しようとしたほうのSQL文の実行が失敗します)。 テーブルの構造をSQL文で書けば、次のようなものでしょう (あくまでも例です)。 ``` CREATE TABLE sample ( name varchar(100), url varchar(191) UNIQUE KEY, bangou int ) CHARACTER SET utf8; ``` url列に一意キー (UNIQUE KEY) を使うか主キー (PRIMARY KEY) を使うかは実際のテーブル定義にあわせて決めてください。