#6641 closed Uncategorized (fixed)
Concurrency issue with get_or_create
Reported by: | JEFFGUINNESS | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | get_or_create |
Cc: | tomasz.zielinski@…, gerdemb | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This is from Travis Terry post on http://groups.google.com/group/django-developers/browse_thread/thread/9730f4005bf08b67 and where he is much more eloquent then I am, I will post his some of his comments.
Two threads/processes/servers (let's call them P1 and P2) need to
concurrently create a unique object
- P1 calls get_or_create(), which tries to get the item (it doesn't exist)
- P2 calls get_or_create(), which tries to get the same item (it doesn't exist)
- P1's get_or_create() tries to create the item (this works and returns the item)
- P2's get_or_create() tries to create the item. One of two things happens:
- a second item is created with the same parameters if this doesn't violate a UNIQUE constraint
- the second create fails (because of a UNIQUE constraint) and raises an exception
The following pseudo-code handles the problem:
def get_or_create(**kwargs): try: obj = get(**kwargs) except: try: obj = create(**kwargs) except: obj = get(**kwargs) return obj
Attachments (2)
Change History (11)
by , 17 years ago
Attachment: | query.diff added |
---|
comment:1 by , 17 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
This really doesn't feel like it warrants inclusion in Django's core, since a site which has traffic patterns that would generate this problem can easily use something like Marty's suggestion in the mailing-list thread.
comment:2 by , 17 years ago
Patch needs improvement: | set |
---|---|
Resolution: | wontfix |
Status: | closed → reopened |
Triage Stage: | Unreviewed → Accepted |
This patch isn't too intrusive and I can't imagine how it will fail incorrectly. Plus it doesn't add a lot of overhead. So, sorry James... I realise it's borderline, but I think it might be worth it.
Patch needs improvement, though. Catching Exception is wrong. You're looking for IntegrityError, so catch it. That's one of the exceptions we carefully promote into django.db.backends so it's portable.
comment:3 by , 17 years ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
Marking as ready since the new patch addresses malcom's comments.
comment:4 by , 17 years ago
Version: | 0.96 → SVN |
---|
Changing the version, the patch applies to SVN (and qsrf by the look of it, the issue is still present there).
comment:5 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
comment:6 by , 14 years ago
Easy pickings: | unset |
---|---|
Severity: | → Normal |
Type: | → Uncategorized |
I think the problem is still there: http://stackoverflow.com/questions/2235318/how-do-i-deal-with-this-race-condition-in-django/2235624#2235624
comment:7 by , 14 years ago
Cc: | added |
---|
comment:8 by , 14 years ago
A django-developers thread discussing this problem: http://groups.google.com/group/django-developers/browse_thread/thread/5387a20958443b15
comment:9 by , 13 years ago
Cc: | added |
---|---|
UI/UX: | unset |
Diff file