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.

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