9👍
Doing select_for_update()
on an EventRegistration
queryset isn’t the way to go. That locks the specified rows, but presumably the conflict you’re trying to prevent involves creating new EventRegistrations
. Your lock won’t prevent that.
Instead you can acquire a lock on the Event
. Something like:
class Event(models.Model):
...
@transaction.atomic
def reserve_tickets(self, number_tickets):
list(Event.objects.filter(id=self.id).select_for_update()) # force evaluation
if self.get_number_of_registered_tickets() + number_tickets <= self.capacity:
# create EventRegistration
else:
# handle error
Note that this uses the transaction.atomic
decorator to make sure you are running inside a transaction.
4👍
Note that in multiple database environment you must have atomic
and select_for_update
on the same db, otherwise it wont work
with transaction.atomic(using='dbwrite'):
Model.objects.using('dbwrite').select_for_update()....
Source:stackexchange.com