20239


環境  
PHP 5.3.19  
Cakephp 2.6.1  
MySQL 5.067

1日1回、別システムから受け取ったCSVファイルを解析し、データベースに登録する処理を書いて運用しています。  
処理としては、テーブルのデータを初期化して、全て挿入することにしています。  
普段は一意に登録されるのですが、たまにデータが2重に登録される場合があります。  
※例：5万件のデータを挿入すると、10万件になっている  
問題発生時のログを取ってみても、挿入したクエリは全て一意で重複はありませんでした。

原因は何なのでしょうか？  
よろしくお願い致します。

下記に簡易的な処理を書きます。

[code]

    class ConvertCsvController extends AppController {
    　　public function exec(){
    　　　　//csvからデータ生成
    　　　　$class = new hoge1();
    　　　　$this->updateToClass($class);
    
    　　　　//csvからデータ生成2
    　　　　$class = new hoge2();
    　　　　$this->updateToClass($class);
    　　}
    
    　　private function updateToClass($class){
    　　　　set_time_limit(600);
    
    　　　　//pdoでDBにアクセス（省略
    　　　　$pdo = new PDO();　
    
    　　　　//テーブルを初期化
    　　　　$pdo->query("TRUNCATE ".$class->TABLE_NAME);
    
           //トランザクション開始
           $pdo->query("START TRANSACTION");
    
           try {
    　　　　  foreach ( $file as $key => $line ) {
    　　　　　  　//内容の生成処理は省略
    　　　　  　　//(null,1,2,3,"hoge")みたいなのが出来る
    　　　  　　　$values = $line;
    　　  　　　　if( !empty( $insert_values ) ){
    　  　　　　　　　$insert_values .= ", ";
      　　　　　　}
      　　　　　　$insert_values .= "(". $values . ")";
      　　　　　　$insert_count++;
    
    　　　　　  　if($insert_count > 5000){
    　　　　  　　　　$pdo->query($class->INSERT_HEAD.$insert_values);
    　　　  　　　　　$insert_values = "";
    　　  　　　　　　$insert_count = 0;
    　  　　　　　}
      　　　　}
      　　　　//余ったのを入れる
      　　　　if($insert_count > 0){
    　　　　　  　$pdo->query($class->INSERT_HEAD.$insert_values);
    　　　　  }
             $pdo->query("COMMIT");
    
           } catch (PDOException $e) {
            $pdo->query("ROLLBACK");
            echo 'Connection failed: ' . $e->getMessage();
            return false;
           }
    
    　　}
    }
    
    
    //テストクラス、hoge2も同じ形式
    class hoge1{
    　　public $FILE_PATH = "hoge1.CSV";
    　　public $TABLE_NAME = "hoge1";
    　　
    　　public $INSERT_HEAD = "INSERT INTO `hoge1` (
    　　　　`id`, `customer_code`, `spot_code`, `spot_1`, `spot_2`, `place_1`, `place_2`, `center_id`, `center_name`, `business_id`, `business_name`, `create_date`, `update_date`
            ) VALUES ";
    }
    
[/code]

【2015/12/29 追記】  
トランザクションを試して様子を見ていましたが問題が再発しました。  
※レコード内容まではログをとっておらず、insertの発行回数だけ取得していましたが、  
5000 * 11で約55000件なのに、レコードは１０万件になっていました。


CC BY-SA 3.0
2015-12-21T02:39:17.777
20238
2015-12-29T01:57:48.637
2015-12-29T01:57:48.637
10977
10977
question
php mysql cakephp pdo
Cakephpでデータが二重に保存される


テーブルロックでトランザクションを掛けてはいかがでしょうか?  
上記ソースだとコンストラクタ、デストラクタに仕掛けるのが手軽に検証できますね。

または、クエリが一意ということで、二重登録になるケースがわかりませんが、  
一意であるべきフィールドにユニーク制約を設定しておくのも良いかと思います。

上記で重複エラーになるかどうかを検証すれば、二重にバッチが走っているかもわかると思います。  
より原因究明に近づくことでしょう。


CC BY-SA 3.0
2015-12-21T03:27:27.550
20239
2015-12-21T05:27:06.817
2015-12-21T05:27:06.817
12906
12906
20238
answer