#21171: Skip transaction creation for single statement operations
-------------------------------------+-------------------------------------
     Reporter:  Anssi Kääriäinen     |                    Owner:  nobody
         Type:                       |                   Status:  closed
  Cleanup/optimization               |
    Component:  Database layer       |                  Version:  1.5
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  fixed
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Florian Apolloner <apollo13@…>):

 * status:  new => closed
 * resolution:   => fixed


Comment:

 In [changeset:"bc7dd8490b882b2cefdc7faf431dc64c532b79c9" bc7dd849]:
 {{{
 #!CommitTicketReference repository=""
 revision="bc7dd8490b882b2cefdc7faf431dc64c532b79c9"
 Fixed #21171 -- Avoided starting a transaction when a single (or atomic
 queries) are executed.

 Checked the following locations:

  * Model.save(): If there are parents involved, take the safe way and use
    transactions since this should be an all or nothing operation.

    If the model has no parents:

     * Signals are executed before and after the previous existing
       transaction -- they were never been part of the transaction.

     * if `force_insert` is set then only one query is executed -> atomic
       by definition and no transaction needed.

     * same applies to `force_update`.

     * If a primary key is set and no `force_*` is set Django will try an
       UPDATE and if that returns zero rows it tries an INSERT. The first
       case is completly save (single query). In the second case a
       transaction should not produce different results since the update
       query is basically a no-op then (might miss something though).

  * QuerySet.update(): no signals issued, single query -> no transaction
    needed.

  * Model/Collector.delete(): This one is fun due to the fact that is
    does many things at once.

    Most importantly though: It does send signals as part of the
    transaction, so for maximum backwards compatibility we need to be
    conservative.

    To ensure maximum compatibility the transaction here is removed only
    if the following holds true:

      * A single instance is being deleted.
      * There are no signal handlers attached to that instance.
      * There are no deletions/updates to cascade.
      * There are no parents which also need deletion.
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/21171#comment:5>
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/066.8f7641a429eb9d1adec3df029499e82f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to