Invental/Review lessons/Check, then act on stale state

Check, then act on stale state

Lock the rows before removing the last owner

“Refuse to remove the last owner” is a concurrency rule, not an if: unless the rows you count are locked in the same transaction as the delete, two admins can each remove “the other” owner at the same moment.

01 · Before and afterThe pattern

SQL
BEGIN;
SELECT id FROM members WHERE workspace_id = $1 AND role = 'owner' FOR UPDATE;  -- lock the set you count
SELECT count(*) FROM members WHERE workspace_id = $1 AND role = 'owner';      -- now stable
-- if count <= 1 and the target is an owner: ROLLBACK with an error
DELETE FROM members WHERE workspace_id = $1 AND user_id = $2;
COMMIT;

02 · Run it on your appThe check

Can two people, clicking at the same time, remove every owner of a workspace in your app?

If the honest answer is no or not sure, this is worth a look before it reaches production.

Want this checked on your code?

Tell us what you are building and what worries you. We match a senior reviewer to your code and confirm scope before anything starts.

— Get in touch
hi@invental.co ↗
— Or
— What to include

A link or short description of the code or system, what you want checked, your stack, and when you need the answer. No repository access is needed until scope is agreed.

— Or leave a note
We reply within one business day.