0

テーブル内の行を「使用中」としてロックしようとしています。これにより、cron が毎分実行されるときにデータを 2 回処理することはありません。スクリプトの実行に時間がかかるため、cron を使用すると、スクリプトの複数のインスタンスが一度に実行されます (通常、一度に約 5 つか 6 つ)。何らかの理由で、「使用中」の方法が常に機能するとは限りません。

テーブルを同時に処理できるようにする必要があるため、テーブルをロックしたくありません。そのため、「inuse」フィールドを使用して個々の行を疑似ロックするルートをたどりましたこれを行うためのより良い方法を知りません。

これが私のジレンマの実例です:

 <?
    //get the first row from table_1 that is not in use
    $result = mysqli_query($connect,"SELECT * FROM `table_1` WHERE inuse='no'");
    $rows = mysqli_fetch_array($result, MYSQLI_ASSOC);
    $data1 = $rows[field1];

    //"lock" our row by setting inuse='yes'
    mysqli_query($connect,"UPDATE `table_1` SET inuse='yes' WHERE field1 = '$data1'");

    //insert new row into table_2 with our data if it doesn't already exist
    $result2 = mysqli_query($connect,"SELECT * FROM `table_2` WHERE field='$data2'");
    $numrows = mysqli_num_rows($result2);
    if($numrows >= 1) { 
      //do nothing
    } else {
      //run some unrelated script to get data
      $data2 = unrelatedFunction();

      //insert our data into table_2
      mysqli_query($connect,"INSERT INTO `table_2` (field) value ('$data2')");
    }

    //"unlock" our row in table_1
    mysqli_query($connect,"UPDATE `table_1` SET inuse='no' WHERE field1 = '$data1'");
 ?>

ここで、$data2 を含む行が既に存在する場合、$data2 は収集および挿入されないことがわかりますが、その部分はエラー チェック用であり、エラーがまだ発生するため、私の質問には答えません。その理由を理解しようとしています (そこにエラーチェックがない場合)、「inuse」メソッドが無視されることがあり、table_2 に $data2 が含まれる重複行が取得されます。

4

1 に答える 1