次のような mysql デッドロック エラーが発生することがあります。
'ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してみてください」
複数のphpプロセスが同時に実行され、テーブルから行を選択しているキューテーブルがあります。ただし、プロセスごとに、フェッチごとに一意の行のバッチを取得する必要があるため、重複する行が選択されないようにします。
だから私はこのクエリを実行します:(これはデッドロックエラーが発生するクエリです)
$this->db->query("START TRANSACTION;");
$sql = " SELECT mailer_queue_id
FROM mailer_queues
WHERE process_id IS NULL
LIMIT 250
FOR UPDATE;";
...
$sql = "UPDATE mailer_queues
SET process_id = 33044,
status = 'COMPLETED'
WHERE mailer_queue_id
IN (1,2,3...);";
...
if($this->db->affected_rows() > 0) {
$this->db->query("COMMIT;");
} else{
$this->db->query("ROLLBACK;");
}
私もよ:
同時にテーブルに行を挿入する(トランザクション/ロックなし)
テーブル内の行を同時に更新する(トランザクション/ロックなし)
同時にテーブルから行を削除する(トランザクション/ロックなし)
同様に、私の更新と削除は、process_idが割り当てられている行のみを更新および削除します...そして、「SELECT行... FOR UPDATE」というトランザクションを実行する場所は、process_id = nullです。理論的には、それらが重複することはありません。
これらのデッドロックを回避する適切な方法があるかどうか疑問に思っていますか?
あるトランザクションがテーブルの選択/更新中にテーブルを長時間ロックし、別のプロセスが同じトランザクションを実行しようとしてタイムアウトしたためにデッドロックが発生する可能性はありますか?
どんな助けでも大歓迎です