Per il blocco ottimistico è necessario definire alcuni mezzi per verificare se una riga è cambiata dall'ultima volta che l'hai vista. Ad esempio, aggiungiamo semplicemente un altro identificatore:
alter table regions_indexes add version_id integer default 1 not null;
Ora l'applicazione legge alcune righe, mostra i dati all'utente e attende fino a quando non viene fatto clic sul pulsante. Dobbiamo ricordare il valore di version_id
abbiamo.
Dopo aver cliccato il pulsante, si eseguono tutti i calcoli necessari. Quando sei pronto per aggiornare la riga, la blocchi e controlli se version_id
non è cambiato. In caso contrario, incrementa version_id
e impegnarsi. In tal caso, sfortuna --- devi dire all'utente di ripetere l'operazione perché qualcuno lo ha superato.
Potrebbe assomigliare a questo (in pseudocodice):
-- 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;
Ma il blocco ottimistico non funziona bene in situazioni di alta concorrenza. Quando i conflitti non sono rari, dovrai riavviare le transazioni frequentemente.