#15507: Savepoint support for MySQL backend
------------------------------------------+---------------------------------
 Reporter:  lamby                         |          Owner:  nobody    
   Status:  new                           |      Milestone:            
Component:  Database layer (models, ORM)  |        Version:  1.2       
 Keywords:                                |   Triage Stage:  Unreviewed
Has patch:  1                             |  
------------------------------------------+---------------------------------
 Currently, it is not possible for the following code to deadlock when
 using the MySQL backend:

 {{{#!python
 from django.db import models, transaction

 class Parent(models.Model):
     lookup = models.CharField(max_length=20, unique=True)
     num_children = models.IntegerField(default=0)

 class Child(models.Model):
     parent = models.ForeignKey(Parent, related_name='children')
     name = models.CharField(max_length=20)

     def save(self, *args, **kwargs):
         created = not self.pk

         super(Child, self).save(*args, **kwargs)

         if created:
             Parent.objects.filter(pk=self.parent_id).update(
                 num_children=models.F('num_children') + 1,
             )

 @transaction.commit_on_success
 def my_view(request):
     parent = Parent.objects.get_or_create(lookup='a')
     parent.children.create(name='foo')
 }}}

 This is because the `INSERT` in `get_or_create` gains an `IX` lock on that
 row even though it fails and raises `IntegrityError`. This lock causes the
 deadlock later on when `UPDATE` is called from `Child.save`.

 Adding savepoint support would fix this as the rollback to savepoint made
 just before the `INSERT` would remove the `IX` lock.

 Patch attached. Tested on 5.0.84-1.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/15507>
Django <http://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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to