Fix race in get_or_create() which can lead to update
|Reported by:||Richard Davies <richard.davies@…>||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||master|
|Cc:||richard.davies@…||Triage Stage:||Design decision needed|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
There is a race condition in get_or_create - if the object is not present for the initial get(), but is swiftly created elsewhere, then the save() will update the object created elsewhere and return it with created=True.
This patch uses save(force_insert=True) to stop this from happening, and to drop through into the existing code that re-attempts the get(). I also update some of the documentation to make the behavior completely clear.
Note: Patch follows discussion with Malcolm at http://groups.google.com/group/django-developers/browse_thread/thread/179ed55b3bf44af0/067be6c02aba2bb3?hl=en#067be6c02aba2bb3
I am only submitting the patch to get_or_create(), which seemed uncontroversial. I personally believe that a similar force_insert=True should be used in create(), or if not then at least that force_insert and force_update flags should be available for create() as well as for save().
Change History (11)
comment:1 Changed 6 years ago by jacob
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
- Triage Stage changed from Unreviewed to Design decision needed
comment:3 Changed 6 years ago by mtredinnick
- Resolution set to fixed
- Status changed from new to closed