I ran into a problem when I have a function that needs serialized access, depending on some circumstances. This seemed like a good case for using advisory locks. However, with a rather heavy load, I found that serialized access does not occur, and I see parallel access to this function.
The purpose of this function is to provide "inventory control" for the event. This means that it is supposed to limit the simultaneous purchase of tickets for this event so that the event is not oversold. These are the only advisory locks used in the application / database.
I find that sometimes there are more tickets in an event than the value of eventTicketMax. It does not look like it should be possible due to advisory locks. When testing with small volume (or with manual delays, such as pg_sleep after acquiring a lock), everything works as expected.
CREATE OR REPLACE FUNCTION createTicket( userId int, eventId int, eventTicketMax int ) RETURNS integer AS $$ DECLARE insertedId int; DECLARE numTickets int; BEGIN
Here is my environment setup:
- Django 1.8.1 (django.db.backends.postgresql_psycopg2 w / CONN_MAX_AGE 300)
- PGBouncer 1.7.2 (session mode)
- Postgres 9.3.10 on Amazon RDS
Additional variables that I tried to configure:
- setting CONN_MAX_AGE to 0
- Remove pgbouncer and connect directly to DB
In my testing, I noticed that in cases where the event was resold, tickets were purchased from different web servers, so I don’t think there is any kind of funny business about a joint session, but I can’t say for sure.
source share