#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.