i have accounts
model in django project, stores account balance(available money) of users. every deduction account of users preceded amount check i.e. check if user has x amount of money or more. if yes go ahead , deduct amount.
account = accountdetails.objects.get(user=userid) if int(account.amount) >= fare: account.amount = account.amount-fare account.save()
now want put lock in first .get()
statement, race conditions can avoided. user makes request twice, , application executes above code twice simultaneously, causing 1 of requests override other.
i found out select_for_update() want. locks row until end of transaction.
account = accountdetails.objects.select_for_update().get(user=userid)
but it's available in django 1.4 or higher , i'm still using django 1.3 , moving new version can't done right now. ideas how can achieve in present django version?
looks you'll have use raw sql. had through current code , think more hassle try , backport write sql.
account = accountdetails.objects.raw( "select * yourapp_accountdetails update user = %s", [user.id] )
for convenience , keep code dry can add method accountdetails model or something.
class accountdetails(models.model): @classmethod def get_locked_for_update(cls, user): return cls.objects.raw( "select * yourapp_accountdetails update user = %s", [user.id] )
yourapp
name of application have given when ran startapp. i'm assuming have foreign key relationship on accountdetails user model of kind.
the current implementation of select_for_update on django 1.5 looks this:
def select_for_update(self, **kwargs): """ returns new queryset instance select objects update lock. """ # default false nowait nowait = kwargs.pop('nowait', false) obj = self._clone() obj.query.select_for_update = true obj.query.select_for_update_nowait = nowait return obj
so that's pretty simple code. setting few flags on query object. flags won't mean when query executed. @ point you'll need write raw sql. @ point need query on accountdetails model. put there now. maybe later you'll need on model. that's when you'll have decide how share code between models.
Comments
Post a Comment