I have a table my_table
in PostgreSQL v 12 which has two fields called id
and status
.
I need to write a stored procedure updateStatus
which has three parameters (id
, oldStatus
and newStatus
). It should update the row's status to newStatus
only if it is in oldStatus
at the moment and (do something else otherwise like throwing an exception). The procedure should work well in concurrent mode.
What is the best way to achieve this?
I thought of the way suggested here: Atomic UPDATE .. SELECT in Postgres
Is it OK? Or perhaps there is an easier way to achieve the same effect?
LOOP
UPDATE my_table
SET status = _new_status_
WHERE id = (SELECT id FROM my_table WHERE id = _id_ status = _old_status
FOR UPDATE SKIP LOCKED); -- pg 9.5
CONTINUE WHEN FOUND;
UPDATE my_table
SET status = _new_status_
WHERE id = (SELECT id FROM my_table WHERE id = _id_ and status = _old_status
FOR UPDATE);
EXIT WHEN NOT FOUND; -- throw some error perhaps etc
END LOOP;