Erstens: MySQL ist eine der schlechtesten Software, um dies zu implementieren, insbesondere wenn es sehr dynamisch ist. Der Grund dafür ist, dass Engines wie MEMORY und MyISAM nur vollständige Tabellensperren haben, während geeignetere Engines wie InnoDB eine höhere Schreibstrafe haben (um ACID-Eigenschaften bereitzustellen) und für den Zugriff auf Datensätze optimiert sind, die räumlich und zeitlich geschlossen sind (diese sind im Speicher festgelegt) ). Es gibt auch kein gutes Änderungsbenachrichtigungssystem für MySQL - es muss als Abfrage implementiert werden. Es gibt Dutzende von Softwareteilen, die für diese Aufgabe optimiert sind .
Trotzdem habe ich gesehen, dass diese Art des Zugriffs erfolgreich implementiert wurde, wenn die Leistungs- / Effizienzanforderungen nicht sehr hoch sind. Viele Menschen können es sich nicht leisten, nur für einen kleinen Teil der Geschäftslogik eine vollständig separate Technologie einzuführen und zu warten.
SELECT FOR UPDATE
ist das, wonach Sie suchen - lesen Sie die Serialisierung. Während ein UPDATE / DELETE die Zeile während einer laufenden MYSQL-Transaktion immer sperrt, möchten Sie möglicherweise eine große Transaktion vermeiden, während der Prozess ausgeführt wird.
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 sorgt dafür, dass alle gleichzeitigen Auswahlen bis auf eine gesperrt werden, wenn Zeilen ausgewählt werden. Da dies zu vielen gesperrten Verbindungen gleichzeitig führen kann, halten Sie die anfängliche Transaktion so klein wie möglich und versuchen Sie, mehr als eine Zeile gleichzeitig zu verarbeiten.