Bei der Implementierung einer Job Queue in SQL gibt es viele potenzielle Fehlerquellen und unerwünschte Verhaltensweisen. Glücklicherweise gibt es eine einfache Funktion, um Fehler zu vermeiden: FOR UPDATE SKIP LOCKED
genutzt wird.
Dieser Befehl sperrt die ausgewählte Zeile für weitere Lese- und Schreibvorgänge, solange die Transaktion läuft. So kann die Job-Warteschlange mit beliebig vielen Worker Threads oder Server-Nodes ohne Sorge vor Duplikaten von Jobs aufgerufen werden.
Ein einfaches Beispiel hierfür:
1DELETE FROM jobs
2WHERE id = (
3 SELECT id
4 FROM jobs
5 ORDER BY id
6 FOR UPDATE SKIP LOCKED
7 LIMIT 1
8)
9RETURNING *;
Die Ausführung der Abfrage innerhalb einer Transaktion gibt den nächsten zu bearbeitenden Job zurück und löscht diesen nach Abschluss der Transaktion. Solange die Transaktion offen ist, ist die Ergebniszeile für weitere Lese-/Schreibvorgänge gesperrt. Am Ende wird der Job auch in derselben Transaktion aus der Tabelle gelöscht. Falls der Job nicht korrekt bearbeitet werden konnte und einen Fehler verursacht, kann die Transaktion zurückgesetzt werden, was die Zeile wieder entsperrt und sie nicht löscht.
Das direkte Löschen der Zeile in dieser Abfrage ist jedoch optional. Bei einem Fehler können Sie den Job als „fehlgeschlagen" markieren und ihn bei weiterer Ausführung überspringen. Deshalb genügt die inner selection für die Funktion der Job Queue, solange Sie das zusätzliche Update bzw. Löschen in derselben Transaktion durchführen.