Para el bloqueo optimista, debe definir algunos medios para verificar si una fila ha cambiado desde la última vez que la vio. Por ejemplo, agreguemos otro identificador:
alter table regions_indexes add version_id integer default 1 not null;
Ahora la aplicación lee alguna fila, muestra los datos al usuario y espera hasta que se hace clic en el botón. Debemos recordar el valor de version_id
tenemos.
Después de hacer clic en el botón, realiza todos los cálculos necesarios. Cuando esté listo para actualizar la fila, bloquee la fila y compruebe si version_id
no ha cambiado. Si no es así, incrementa version_id
y cometer Si es así, mala suerte:debe decirle al usuario que repita la operación porque alguien lo supera.
Puede verse así (en pseudocódigo):
-- 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;
Pero el bloqueo optimista no funciona bien en situaciones de alta concurrencia. Cuando los conflictos no son raros, deberá reiniciar las transacciones con frecuencia.