人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHP・MySQL・PDO・シェルスクリプトで質問です。MySQLからPDOで大量にINSERTする場合、MySQL・PDOではINSERTが完了していないのにPHPは次行へ移動することはありますか?あるとすれば移動しないようにする対策はありますか?
外部からフォルダへデータファイルが新しく置かれたら(←A)Aを一度にMySQLへINSERTするPHP(←B)と、INSERT内容を元に編集するPHP(←C)を作りました。
これらを円滑且つ重複なく稼働する為、CRONから1分毎に呼び出されるシェルスクリプトでは上記各処理の動作中フラグがなければ、それぞれ呼び出す形にし、その際Bを呼び出す行下にはフラグファイル(B')を作成することで、Cの冒頭ではB'がなければ起動できないようにしました。
これでBが完了しなければCに進めないようにしたところ、確かにA→B→C順に動いたのですが、場合によってBでMySQLへINSERT中?にCへ進む場合がありました。結果C判定が異常になる場合が発生しています。
とりあえずCの手前にSleepを入れて対応しますが、根本的解決ではないので悩んでいます、
以上、抽象的な話で恐縮ですが、何かアドバイスいただければ幸いです。よろしくお願い致します。
ちなみにPHP5.3.3・Mysql14.14です。

●質問者: くじぇ
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● degucho
●167ポイント

SQL実行に失敗したまま続行している可能性があります。
http://piyopiyocs.blog115.fc2.com/blog-entry-657.html
エラーコードを拾うか、Exceptionを拾ってみてください


くじぇさんのコメント
deguchoさんありがとうございます。 エラーは出ませんでした。

2 ● phplove
●167ポイント

Bの処理が多重で動くことはないでしょうか?
Aのファイルが時間差で置かれたような場合とか。
Bの処理が動いているときは次のBの処理もブロックする必要があるかと思います。


phploveさんのコメント
あとトランザクション使った方が良いです。

くじぇさんのコメント
phploveさんありがとうございます。 ログによると、Bが多重で動いていることはないようです。 ただ今までAが時間差で置かれたこともないですが。 Bの処理が動いているときは次のBの処理もブロックする処理は入れています。 トランザクションも入れています。

3 ● ビ=ヨンセ
●166ポイント

実際のソースを見てみないと何とも言えませんがCが終了しないうちに次のBが動いているのではないかと思います。
cronで定期的に起動するのはBだけにしておいて、BからCを呼び出す形にするべきです。
Bを呼び出す際には、BもCも動作中ではないことを確認するようにします。


くじぇさんのコメント
ビ=ヨンセさんありがとうございます。 PHPで「外部からフォルダへデータファイルが新しく置かれたらイベント発生」というのができるならAをcronで動かす必要はないと私も思うのですが、やり方が分かりません。

TransFreeBSDさんのコメント
linuxならincronってのがある様です。 http://qiita.com/k-suzuki/items/4a94ebeda9ec75fdad40 ただ、ロックのためにファイルを作ってるのが同じディレクトリなら、そのイベントも拾っちゃいますので、別ディレクトリにするか、flockとかにした方が良いんじゃないでしょうか。 あと、これだけだと異常終了時の再キックがなくなるので、結局はcronでの監視も必要ではあると思います。 本題の方は、C中のB起動の他、Cの多重起動もありえませんか? 編集ってのが何の編集か分かりませんが、ロックとかコミット/ロールバックの整合性とかどうなんでしょう。 素直に考えればBからCを起こすのがいいですが、それが無理なら、Bでファイルを消して、incronで感知してCを起動ってのもいいかもしれません。 いずれにしても異常時のロックの整合性とリカバリは十分検討する必要あると思いますが。

くじぇさんのコメント
ビ=ヨンセさんありがとうございます。 incronは初耳でした! 参考にさせていただきます。

ビ=ヨンセさんのコメント
ひとつまえのコメントは私ではありませんw 私の想定ではAはcronでの起動だろうと考えておりました。 きっちりとデータを置いたときの同期を取りたいのであれば、ファイルがあるかどうかの監視ではなく、なにかしらのプログラムを動かして「ファイルを置いた」というトリガーを受け付けてBの処理を起動するべきだとおもいます。 Bの処理をPHPで書くならApacheの元で動作させることができるわけですから、HTTPでリクエストを出してもらえばいいのではないかと思います。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ