ページを見るとカウントをとるプログラムを書きました。
※idをユニークに設定。mysql使用。
閲覧やリロードでidのレコードデータがない場合は、レコード(numberは1)を挿入。
既にidがある場合は、numberに+1してカウントしていくものです。
$request_data=$pdo->
prepare("
INSERT INTO table
(id,number)
VALUES
(:id,1)
ON DUPLICATE KEY UPDATE
number = number+1
");
$request_data->bindValue(":id",$id);
$request_data->execute();
上記のプログラムだと、挿入や更新自体は問題がありません。
しかし、idの無いデータで挿入を行ったにも関わらず、numberの値が2となったり、更新時に+2されることがあります。
※うまくいく時とうまくいかない時があります。閲覧やリロードは1回のみ。
また、データベースをみていると後から遅れてデータが入ってくる時もあります。
データベースの遅延?トラブル?とも考えられますが、解決法として何が考えられるでしょうか?
そのプログラムは、自分一人で使ってる、という状況でしょうか。
例えば、テスト中だから公開してない、とか、ローカルな環境で動いてる、とか。
本当に自分の目の前で動かしているものだけなのかどうかは、クエリログを取ってみるのが確実です。
http://server-setting.info/centos/mysql-log-type.html
一人で使っているということが確実ならば、気になるのは commit です。
「DB に、遅れて書き込まれている」というのが引っ掛かります。
質問の文面のコードには書かれていませんが、PDO::commit は、きちんと呼び出しているでしょうか?
回答ありがとうございます。
公開はしていますが、テスト中なので他のアクセスはない状態です。
他の競合がいるわけではないのでトランザクションは設定していませんでした。
可能性はありますね。試してみます。
//トランザクション開始
$pdo->beginTransaction();
$request_data=$pdo->~~
//commit
$pdo->commit();
としてみましたが、勝手に数値が増加しています。
これはこの部分だけで無く、他のプログラムが干渉している様な全体として何か間違っている可能性が高そうです、、。
結局、何を設定しても問題点は解決できませんでした。
対応策として、ページが読み込まれた後にajaxでデータを飛ばして、別ページのphpファイルで処理するようにしてカウントするようにしました。
この方法だと問題が出なかったので、何かページ内部のプログラムが干渉していたか、ブラウザの挙動に関してつかみ切れていなかったのかもしれません。
真相が掴めなかったのは残念でしたが、みなさんご協力ありがとうございました。
08/25 追記
いろいろと検証をしてみました。
結果、ひとつのページにいくつかのクエリがある中、あるクエリで著しく遅くなっているものを見つけました。2秒程度。
※近い位置にソーシャルボタンを設置していたので、ページの読み込みが遅いのはソーシャルボタンが要因であると思い込んでいました。
どうも原因はそれだったようで、そのクエリを改善した結果、問題の複数カウントなどの現象はなくなりました。
PHPの挙動についてはっきりと認識しているわけではありませんが、ひとつのクエリが遅い場合、他のクエリが影響を受けて複数実行してしまう事もあるようです。※予測であり未確認
ajaxにすると適正値が挿入されたのは、jqueryを使用していたためページが読み込まれた後に実行されたせいかもしれません。
回答ありがとうございます。
2014/08/16 21:26:23