select for update

Hallo zusammen,

ich habe ein kleines Problem mit einer SELECT FOR UPDATE-Abfrage und ich hoffe, dass ihr mir helfen könnt.

Ausgangssituation: Ich habe eine Tabelle mit Daten, die von mehreren angebundenden Clients “abgearbeitet” wird - d.h. die Clients ziehen sich Daten, bearbeiten und löschen diese danach. Dies passiert so lange bis die Tabelle leer ist. Wichtig: Es muss verhindert werden, dass sich zwei Clients die gleichen Datensätze ziehen.

Meine Überlegung war jetzt, dies mit SELECT FOR UPDATE zu machen. Nach der Doc werden die gezogenen Zeilen für andere SELECT FOR UPDATE-Anfragen gesperrt, bis die Daten bearbeitet (ändern/löschen) wurden.

In einem Testszenario schlägt dies allerdings fehl. Jeder Client bekommt die gleichen Daten geliefert und keiner bekommt ein LOCK.

Hat einer eine Idee voran dies liegen kann? Oder gibt es noch einen anderen Lösungsansatz für mein Problem?

Danke, mhari

Das heisst ja auch SELECT FOR UPDATE, nicht LOCK for SELECT :smiley:
Jedenfalls wirst du wohl die Bereiche anders aufteilen müssen, auf dem Weg kommst du dafür nicht weiter.

Man könnte natürlich die gesamte Tabelle “locken”, aber das würde ich gerne aus Performancegründen vermeiden. Auf die Idee mit dem SELECT FOR UPDATE bin ich ja nur auf Grund folgender Passage aus der Doc von Postgres gekommen:

FOR UPDATE causes the rows retrieved by the SELECT statement to be locked as though for update. This prevents them from being modified or deleted by other transactions until the current transaction ends. That is, other transactions that attempt UPDATE, DELETE, or SELECT FOR UPDATE of these rows will be blocked until the current transaction ends. Also, if an UPDATE, DELETE, or SELECT FOR UPDATE from another transaction has already locked a selected row or rows, SELECT FOR UPDATE will wait for the other transaction to complete, and will then lock and return the updated row (or no row, if the row was deleted).

Normale SELECTS würden nicht geblockt werden, aber andere SELECT FOR UPDATE müssten einen LOCK erhalten. Dies klappt aber nicht … :confused: