#30375: Use "NO KEY" when doing select_for_update for PostgreSQL
-------------------------------------+-------------------------------------
               Reporter:  mudetz     |          Owner:  nobody
                   Type:             |         Status:  new
  Cleanup/optimization               |
              Component:  Database   |        Version:  1.11
  layer (models, ORM)                |       Keywords:  postgres, lock,
               Severity:  Normal     |  database, operation
           Triage Stage:             |      Has patch:  1
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Currently Django compiles select for update into one of
 - FOR UPDATE
 - FOR UPDATE NOWAIT
 - FOR UPDATE SKIP LOCKED

 All of these acquire a lock which conflicts with `KEY SHARE` locks. This
 means that updates on tables which references a row locked by `FOR UPDATE`
 will have to wait until the lock is released. This is to avoid any
 unexpected changes on `PRIMARY KEY` fields but, **in Django, primary key
 fields are read-only, so locking them makes no sense**.

 There is no need to acquire these kind of locks, instead, we should (at
 least be able to) use
 - FOR NO KEY UPDATE
 - FOR NO KEY UPDATE NOWAIT
 - FOR NO KEY UPDATE SKIP LOCKED

 which can be easily done by overriding BaseOperation.for_update_sql in
 Postgres DatabaseOperation


 {{{
 def for_update_sql(self, nowait=False, skip_locked=False):
     """
     Returns the FOR UPDATE SQL clause to lock rows for an update
 operation.
     """
     if nowait:
         return 'FOR NO KEY UPDATE NOWAIT'
     elif skip_locked:
         return 'FOR NO KEY UPDATE SKIP LOCKED'
     else:
         return 'FOR NO KEY UPDATE'
 }}}

 Not doing so causes lock contention in our use case.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30375>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/049.3b11e730499c792dfc8fba69301aab03%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to