テーブル内の行を「使用中」としてロックしようとしています。これにより、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 が含まれる重複行が取得されます。