Ich habe eine Postgres (9.5) DB für eine Anwendung, die aus Web- und Hintergrund-Worker-Prozessen besteht.Sperren und Entsperren von verschiedenen Postgres-Sitzungen
Wenn wir die HTTP-Anforderung POST /items/123/steps
empfangen, wird die Webanwendung eine Hintergrundaufgabe in die Warteschlange stellen, um einen "Workflow-Schritt" für Element 123 auszuführen und zurückzukehren. Der Artikel entspricht eine Zeile in der Postgres items
Tabelle und hat eine Spalte mit dem ID-Wert 123
Ziel ist es, irgendwie Sperre Artikel 123 für die Verarbeitung, so dass nachfolgende Anforderungen an POST /items/123/steps
werden, bis das Aufgabenelement entriegelt Hintergrunds zurück 123 nach Abschluss seiner Arbeit.
In ähnlicher Weise müssen Anforderungen an GET /items/123
ein Attribut zurückgeben, das angibt, dass Element 123 gesperrt ist, so dass die UI das Element als gerade verarbeitet anzeigen kann, bis die Hintergrundaufgabe es entsperrt.
Da es möglicherweise eine Verzögerung gibt, bis die Hintergrundaufgabe aus der Warteschlange übernommen wird, ist es für die Hintergrundaufgabe nicht ausreichend, Element 123 zu sperren, wenn es gestartet wird. Ich möchte, dass Artikel 123 von der ursprünglichen Webanfrage POST
als gesperrt markiert wird, bis die Hintergrundaufgabe abgeschlossen ist, sodass das Element als für alle Webanforderungen gesperrt angezeigt wird, die vor der Abholung der Hintergrundaufgabe eingehen.
Wenn möglich, möchte ich Postgres verwenden, um dies zu erreichen. Allerdings sind die Optionen, die ich gefunden habe, nicht zu funktionieren scheint:
- Row locks freigegeben werden, wenn die Transaktion endet, die, wenn sie zurückkehrt meine Web-Handler auftritt. Die Hintergrundaufgabe führt ihre Arbeit in verschiedenen Transaktionen aus. So kann ich nicht ein
SELECT FOR UPDATE
auf Element 123. - Eine Sitzungsebene advisory lock kommt näher, außer dass, wenn ich es aus dem Web-Prozess ich kann nicht aus dem Worker-Prozess entsperren, da das Web und Worker jeweils verarbeitet eine eigene Postgres-Sitzung einrichten.
Ich kann durch die Implementierung eines Ad-hoc-Verriegelungsmechanismus dieses Problem umgehen: Fügen Sie eine locked
Spalte items
und es TRUE
im Web Endpunkt gesetzt und dann wieder auf FALSE
im Hintergrund Aufgabe. Wenn es einen standardmäßigen Weg gibt, dies zu tun, würde ich das lieber tun.
Zusätzliche Informationen: Es ist ein Python-Projekt und ich benutze SQLAlchemy, um auf Postgres sowohl von der (Flask) Web App als auch von (Sellerie) Hintergrundaufgaben zuzugreifen. Wenn es einen anderen bewährten Weg gibt, um das Ziel mit diesen Tools zu erreichen, die für mich arbeiten.