Opened 10 years ago

Closed 9 years ago

#24009 closed Uncategorized (needsinfo)

get_or_create can raise an IntegrityError in race conditions

Reported by: Mihail Milushev Owned by: nobody
Component: Uncategorized Version: 1.7
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


get_or_create is described as being atomic in the documentation, but that is not the case. Since it first tries to retrieve an existing record and if that fails it tries to create a new one, another thread can create that record in the small interval between the two operations. This will not result in data corruption as the database will enforce its constraints, but it makes the whole convenience method not that convenient, if I also need to handle this in a try block around its invocation. If I _need_ to do try: get_or_create() except IntegrityError: get() anyway, it makes no sense to use get_or_create in the first place, that logic would work if I just try to create the entity and only retrieve it if the create raises an IntegrityError.

When I call get_or_create I expect it to return the existing record, or to create a new record if one does not exist yet. Getting an IntegrityError there is like saying "there's no existing record, but I cannot create a new one because one already exists".

Change History (4)

comment:1 by Tim Graham, 10 years ago

This may be a duplicate of #13906. Are you using MySQL with REPEATABLE READ?

comment:2 by Mihail Milushev, 10 years ago

No, I'm using PostgreSQL, and wrapping each get_or_create in an individual transaction context will again make get_or_create worthless by requiring at least as much boilerplate around it as it would take to implement the get-or-create logic myself without using get_or_create.

comment:3 by Tim Graham, 9 years ago

As far as I can tell, the IntegrityError you describe should be caught by Django. Did you run into this problem with Django 1.7?

comment:4 by Tim Graham, 9 years ago

Resolution: needsinfo
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top