Pour un verrouillage optimiste, vous devez définir des moyens de vérifier si une ligne a changé depuis que vous l'avez vue la dernière fois. Par exemple, ajoutons simplement un autre identifiant :
alter table regions_indexes add version_id integer default 1 not null;
Maintenant, l'application lit une ligne, montre les données à l'utilisateur et attend jusqu'à ce que le bouton soit cliqué. Nous devons retenir la valeur de version_id
nous avons.
Après avoir cliqué sur le bouton, vous effectuez tous les calculs nécessaires. Lorsque vous êtes prêt à mettre à jour la ligne, vous verrouillez la ligne et vérifiez si version_id
n'a pas changé. Si ce n'est pas le cas, incrémentez version_id
et s'engager. Si c'est le cas, pas de chance --- vous devez dire à l'utilisateur de répéter l'opération car quelqu'un l'a devancé.
Cela peut ressembler à ceci (en 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;
Mais le verrouillage optimiste ne fonctionne pas bien dans une situation de forte concurrence. Lorsque les conflits ne sont pas rares, vous devrez relancer fréquemment les transactions.