Opened 15 years ago

Closed 15 years ago

#13105 closed (duplicate)

[patch] get or create thread safety

Reported by: toplex Owned by: toplex
Component: Database layer (models, ORM) Version: 1.1
Severity: Keywords: thread; multithread; relation; get_or_create
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

If you try get_or_create from several threads at the same time, you'll get duplicates sooner or later. Same goes for adding relations (which checks for duplicates on it's own).
This is a small patch to fix it using a Lock mechanism.
Obviously it won't work when tried from several processes, so I would call it an intermediate patch.
This is my first time touching Django code, so I'm sorry for any screw ups.

Attachments (1)

django-1.1.1-thread-safe.patch (4.3 KB ) - added by toplex 15 years ago.
thread safe get_or_create patch

Download all attachments as: .zip

Change History (2)

by toplex, 15 years ago

thread safe get_or_create patch

comment:1 by Karen Tracey, 15 years ago

Resolution: duplicate
Status: newclosed

For the regular model get_or_create, you won't get duplicates if you have specified the unique constraints on your model/database properly. The routine is coded to rely on the database raising an IntegrityError for duplicates. I assume the same is true for adding relations, though I have not looked closely at that case. If there is a problem for the relation-adding case, when they are defined to Django as unique, then that needs to be spelled out in detail with example models and showing how duplicates can arise.

I don't believe adding a 'fix' for the case where database unique constraints have not be set properly, that only works for multi-thread but not multi-process situations, will help here. We've already got #12759 open for better documentation on get_or_create and the situations where it can be used.

In general we would not add a fix for a multi-process/multi-thread problem that only addresses one of the two environments. In the case of get_or_create, we push the responsibility off to the database, which already has to deal with it.

Also, for the future, patches need to be against trunk, not an existing release (see http://docs.djangoproject.com/en/dev/internals/contributing/#patch-style). The code touched in the patch has changed considerably since 1.1.1. First priority for bug fixes is trunk, and then fixes are backported to the latest release branch. Thus a patch against an old release doesn't help much.

Note: See TracTickets for help on using tickets.
Back to Top