PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Datenbankzeilensperre während mehrerer Transaktionen

Ihre Lösung mit dem Flag scheint machbar und ich denke, das einzige, was benötigt wird, ist, die Sperre ablaufen zu lassen. Grundsätzlich würde ich die Sperre so gestalten, dass ich einen Zeitstempel schreibe, wenn die Sperre genommen wurde, und es so mache, dass der Prozess aktualisieren müsste das Schloss von Zeit zu Zeit (z. B. alle 30 Sekunden), während es noch an der Platte arbeitet. Wenn der Prozess stirbt oder die Arbeit anderweitig nicht abschließt, läuft die Sperre ab und andere Prozesse können entsperren wenn mehr als das Doppelte der Timeout-Periode verstrichen ist.

Wenn ein Prozess die Arbeit an einem Datensatz beendet, würde er das Sperr-Flag löschen und den Datensatz als verarbeitet markieren (wiederum ein weiteres Flag).

Wahrscheinlich möchten Sie zwei Felder haben:eines, das das Zeitstempel-Sperr-Flag speichert, und ein anderes, das anzeigt, welcher Prozess die Sperre besitzt (falls es Sie interessiert). Ich gehe davon aus, dass es eine Art Schlüssel gibt, mit dem die Datensätze in der Tabelle so geordnet werden können, dass das Konzept der "nächsten Aktion" sinnvoll ist.

Sie könnten eine Abfrage wie diese verwenden, um den nächsten zu verarbeitenden Datensatz abzurufen:

 -- find the next available process and "lock" it by updating it's flag
 UPDATE actions_tabe
    SET LockFlag = @timestamp,
        Process = @processname
  WHERE Id IN (SELECT Id
            FROM actions_table
           WHERE LockFlag IS null
             AND IsComplete = '0'
             AND ScheduledTime < now()
           ORDER BY Scheduledtime ASC, Id ASC
           LIMIT 1);

 -- return the Id and Action of the record that was just marked above
 SELECT Id, Action
   FROM actions_table
  WHERE Process = @processname

Beispiel für Fiddle hier:http://sqlfiddle.com/#!11/9c120/26 /1