Opened 6 years ago

Closed 6 years ago

#9581 closed (invalid)

Race condition in Model.save() with non-automatic unique indexes

Reported by: hfaber@… Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

The current Model.save() implementation transparently handles updating of records vs. insertion of new records.
It first tries to update an existing record and if it fails it will do an insert instead.

This can lead to a race condition when between the failed update and the subsequent insert another process successfully inserts an object with the same primary key (or other field with unique index). For automatically generated primary keys (e.g. auto-inc IDs) this is not a problem. But for manually-set PKs (or other unique fields) this will lead to a key integrity violation.

Change History (3)

comment:1 Changed 6 years ago by mrts

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to duplicate
  • Status changed from new to closed

Looks like #2705 would solve this, so closing as duplicate. Please reopen if you think otherwise.

comment:2 Changed 6 years ago by mrts

  • Resolution duplicate deleted
  • Status changed from closed to reopened

I was too quick to dismiss this. #2705 is irrelevant as update is not the problem here. Reopening and letting others decide what to with this.

comment:3 Changed 6 years ago by mtredinnick

  • Resolution set to invalid
  • Status changed from reopened to closed

There are lots of different ways Integrity errors can be raised from a call to save(). If there's a chance that your table structure will hit one of those (e.g. a uniqueness constraint on manually set data), then you have to be prepared to handle the error. How it is handled is not something Django can take care of for you, since the result will be domain-specific. Therefore Django does the only correct thing: raises an IntegrityError.

The admin interface is the one place in Django that does have to handle this stuff automatically, and that will be handled as part of the model-aware validation changes (it's not directly part of that but handling saving of forms there will be necessary and that will show one approach).

So there's no real bug with Django here. The database is the ultimate serialisation point and failures can happen for certain types of data modelling. You have the power to handle that in your code and should do so.

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