Voor optimistische vergrendeling moet u een manier definiëren om te controleren of een rij is gewijzigd sinds u deze de laatste keer zag. Laten we bijvoorbeeld nog een identifier toevoegen:
alter table regions_indexes add version_id integer default 1 not null;
Nu leest de applicatie een rij, toont de gegevens aan de gebruiker en wacht tot er op de knop wordt geklikt. We moeten de waarde van version_id
onthouden we hebben.
Nadat op de knop is geklikt, voert u alle benodigde berekeningen uit. Wanneer u klaar bent om de rij bij te werken, vergrendelt u de rij en controleert u of version_id
is niet veranderd. Als dit niet het geval is, verhoog dan version_id
en plegen. Als dat zo is, heb je pech --- je moet de gebruiker vertellen de handeling te herhalen omdat iemand hem te slim af is.
Het kan er zo uitzien (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;
Maar optimistische vergrendeling werkt niet goed in situaties van hoge gelijktijdigheid. Als conflicten niet zeldzaam zijn, moet u transacties regelmatig opnieuw starten.