まず、MySQLは、これを実装するために考えられる最悪のソフトウェアの1つです。非常に動的な場合は特にそうです。その理由は、MEMORYやMyISAMのようなエンジンは全テーブルロックのみであり、InnoDBのようなより適切なエンジンは(ACIDプロパティを提供するために)書き込みペナルティが高く、空間的および時間的に近いレコードにアクセスするために最適化されている(これらはメモリに設定されている)ためです。 )。MySQLには適切な変更通知システムもありません。これはポーリングとして実装する必要があります。そのタスクのためにさらに最適化された数十のソフトウェアがあります。
そうは言っても、パフォーマンス/効率の要件がそれほど高くない場合は、この種のアクセスを正常に実装するのを見てきました。多くの人々は、ビジネスロジックのほんの一部のために、完全に別個のテクノロジーを導入して維持する余裕はありません。
SELECT FOR UPDATE
あなたが探しているものです-シリアル化を読み取ります。UPDATE / DELETEは、実行中のMYSQLトランザクション中に常に行をロックしますが、プロセスが進行している間は大きなトランザクションを回避したい場合があります。
START TRANSACTION;
SELECT * FROM your_table WHERE state != 'PROCESSING'
ORDER BY date_added ASC LIMIT 1 FOR UPDATE;
if (rows_selected = 0) { //finished processing the queue, abort}
else {
UPDATE your_table WHERE id = $row.id SET state = 'PROCESSING'
COMMIT;
// row is processed here, outside of the transaction, and it can take as much time as we want
// once we finish:
DELETE FROM your_table WHERE id = $row.id and state = 'PROCESSING' LIMIT 1;
}
MySQLは、行を選択するときに、1つを除くすべての同時選択をロックします。これにより、同時に多くのロックされた接続が発生する可能性があるため、初期トランザクションをできるだけ小さくし、一度に複数の行を処理するようにしてください。