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

Optimistische Sperrwarteschlange

Für optimistisches Sperren müssen Sie Mittel definieren, um zu überprüfen, ob sich eine Zeile geändert hat, seit Sie sie das letzte Mal gesehen haben. Fügen wir zum Beispiel einfach einen weiteren Bezeichner hinzu:

alter table regions_indexes add version_id integer default 1 not null;

Jetzt liest die Anwendung einige Zeilen, zeigt die Daten dem Benutzer und wartet, bis auf die Schaltfläche geklickt wird. Wir müssen uns den Wert von version_id merken wir haben.

Nachdem Sie auf die Schaltfläche geklickt haben, führen Sie alle erforderlichen Berechnungen durch. Wenn Sie bereit sind, die Zeile zu aktualisieren, sperren Sie die Zeile und prüfen, ob version_id hat sich nicht geändert. Ist dies nicht der Fall, erhöhen Sie version_id und begehen. Wenn ja, Pech --- Sie müssen dem Benutzer sagen, dass er die Operation wiederholen soll, weil ihm jemand davongelaufen ist.

Es kann so aussehen (in Pseudocode):

-- remember version_id
select *
from regions_indexes
where id = ... and resource_type = ...;

-- wait for user click
-- you can wait for a long time, because no lock is yet acquired
...

update regions_indexes
set current_resource = current_resource - ..., version_id = version_id + 1
where id = ... and resource_type = ...
returning version_id;

if new_version_id = old_version_id + 1 then
  -- success, commit
else 
  -- fail, rollback
end if;

Aber optimistisches Sperren funktioniert nicht gut in Situationen mit hoher Parallelität. Wenn Konflikte nicht selten sind, müssen Sie Transaktionen häufig neu starten.