2016-11-11 5 views
0

Ich habe Multi-Thread-JEE-Anwendung, die SELECT für UPDATE LIMIT 1 ausführen; Abfrage in einer Tabelle mit WHERE-Klausel und Update-Zeile in jeder Transaktion, die Schreibsperre auf Zeilenebene erstellen und Leser nicht zum Lesen blockieren.Postgres Schreiben/Lesen Sperre

Gibt es eine Möglichkeit, Postgres zu konfigurieren, damit die Leser Zeilen mit Schreibsperre lesen?

Antwort

1

Auf Postgres 9.5+ gibt es die Option SKIP LOCKED:

Wenn Sie aus einer Tabelle müssen SELECT und die Zeilen aus wird aktualisiert, bis die Transaktion abgeschlossen ist zu schützen, Sie FOR UPDATE angeben würde, aber wenn einige Zeilen sind gesperrt, Sie können SKIP LOCKED angeben, um die Zeilen einfach zu ignorieren und die Operation nur für die Zeilen auszuführen, auf die sie zugreifen kann.

https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#SKIP_LOCKED

0

Hier ist eine Option für Sie, wenn Sie runnint Postgres < = 9,4, wo NOWAIT existiert, aber SKIP LOCKED sind. Dies zeigt die Verwendung von CONTINUE und EXIT in einem LOOP, um die nächste verfügbare unverriegelte einzelne Zeile zu identifizieren.

DO $$ 
DECLARE 
    r RECORD; 
    ... -- your variables 
BEGIN 
    FOR r IN 
     SELECT some_id 
      FROM some_table 
     WHERE ... -- your conditions 
     ORDER BY ... -- your ordering 
     LIMIT ... -- your limit 
    LOOP 
     BEGIN 
      SELECT ... -- your needed column(s) 
       INTO ... -- your defined variable(s) 
       FROM some_table -- the same table 
      WHERE some_id = r.some_id -- only check this one record 
       FOR UPDATE NOWAIT; -- don't wait for parallel transactions 
      EXIT; 
     EXCEPTION WHEN lock_not_available THEN 
      CONTINUE; 
     END; 
    END LOOP; 
    ... -- do something based on variables, or move this before the EXIT above 
END; 
$$ LANGUAGE plpgsql;