Skip to content

Instantly share code, notes, and snippets.

@rponte
Last active October 30, 2024 13:39
Show Gist options
  • Save rponte/618fdc1b10350b6551ea8f7c8ddf83d3 to your computer and use it in GitHub Desktop.
Save rponte/618fdc1b10350b6551ea8f7c8ddf83d3 to your computer and use it in GitHub Desktop.
PostgreSQL: Playing a little bit with race conditions, SQL and isolation levels
--
-- Trying to buy a new ticket for an event
--
BEGIN;
UPDATE events e
SET updated_at = now()
WHERE e.id = :event_id
AND e.max_tickets > (SELECT count(*) -- (does this logic work with READ_COMMITTED??)
FROM tickets t
WHERE t.event_id = e.id);
if ROW_COUNT == 0 then
RAISE EXCEPTION 'sorry, there is no more tickets to sell'
end if;
INSERT INTO tickets
VALUES (:event_id :customer_id, :code, now());
COMMIT;
@rponte
Copy link
Author

rponte commented Aug 5, 2022

@rafaelpontezup
Copy link

⭐️ The answer to this question:

I've made some integration tests, and this code avoids race conditions when executed inside a transaction that uses the following isolation levels:

  • SERIALIZABLE;
  • REPEATABLE READ;

Any level less strict than those above, as READ_COMMITED, is susceptible to race conditions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment