﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
29786	Add option to lock rows with select_for_update() immediately	ovalseven8	nobody	"In my web application I usually follow the ""fat models, lightweight views"" philosophy.

To put it in a nutshell, I have two models in my app called ""Event"" and ""Registration (for Event)"":


{{{
class Event(models.Model):
    capacity = models.PositiveSmallIntegerField()

    def get_number_of_registered_tickets():
        return EventRegistration.objects.filter(event__exact=self).aggregate(total=Coalesce(Sum('number_tickets'), 0))['total']
    
    @transaction.atomic
    def reserve_tickets(self, number_tickets):
        Event.objects.filter(id=self.id).select_for_update()
        if self.get_number_of_registered_tickets() + number_tickets <= self.capacity:
            # create EventRegistration
        else:
            # handle error


class EventRegistration(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    number_tickets = models.PositiveSmallIntegerField(validators=[MinValueValidator(1)])
}}}

Now, let's say for a specific event only one ticket is left and two users want to buy that ticket concurrently. Under unfortunate circumstances (when I do not use locking), it would be possible that both get the ticket and now I have a problem. So, I need to make sure that the registration for an event happens in sequence. That's the reason why I use **select_for_update()** in the method `reserve_tickets()` above.

Unfortunately, the row is only locked when the QuerySet is evaluates what's not the case here. So, I need more or less a ""dirty hack"" like printing the queryset or creating a list etc.

While this works, I do not think it's a nice solution. Especially for locking rows, I think it would be a good think if Django had a ""lock/evaluate immediately"" option.

Different ideas how the solution API could look like:
`select_for_update().evaluate()`
`select_for_update(evaluate_immediately=True)`

Of course, there're more possibilities. I think it would be a nice little feature and lazy evaluation is something you perhaps do not want for locking.

So my question is if you're open for that, if yes I could look into it."	New feature	new	Database layer (models, ORM)	2.1	Normal				Unreviewed	0	0	0	0	0	0
