38
loading...
This website collects cookies to deliver better user experience
from django.db import models
from django.contrib.auth.models import User
from django.db import models, transaction
class Account(models.Model):
balance = models.IntegerField(default=0)
user = models.ForeignKey(User)
def deposit(self, amount):
self.balance += amount
self.save()
def withdraw(self, amount):
if amount > self.balance:
raise errors.InsufficientFunds()
self.balance -= amount
self.save()
from django.db import models
from django.contrib.auth.models import User
from django.db import models, transaction
class Account(models.Model):
balance = models.IntegerField(default=0)
user = models.ForeignKey(User)
def get_queryset(self):
return self.__class__.objects.filter(id=self.id)
@transaction.atomic()
def deposit(self, amount):
obj = self.get_queryset().select_for_update().get()
obj.balance += amount
obj.save()
@transaction.atomic()
def withdraw(self, amount):
obj = self.get_queryset().select_for_update().get()
if amount > obj.balance:
raise errors.InsufficientFunds()
obj.balance -= amount
obj.save()
User1 acquires a lock on the account
Balance is $1000
User2 attempts to acquire a lock which fails because the account has already been locked by User1
User2 waits for the lock to be released
Balance is $1000 + $100 = $1100
Lock on the account by User1 is released
User2 acquires the lock on the account soon after.