1👍
✅
Using transactions should solve your problem. You didn’t specify your database, but on PostgreSQL with the default transaction isolation level, I believe this will work:
with transaction.atomic():
n_updated = Node.objects.filter(
id=node_id,
volume_count__lt==F('volume_limit')
).update(volume_count=F('volume_count') + 1)
c_updated = Cluster.objects.filter(
id=cluster_id,
volume_count__lt==F('volume_limit')
).update(volume_count=F('volume_count') + 1)
if not (n_updated and c_updated):
# trigger rollback
raise ValidationError("Limit reached")
The key point is that you’re targeting specific rows, and if possible updating them, which will cause other transactions to block if they are trying to update the same rows. Since it’s a transaction, either both updates will succeed or none will.
Source:stackexchange.com