13.07.2017       Выпуск 186 (10.07.2017 - 16.07.2017)       Статьи

Как управлять паралелелизмом в Django моделях


Экспериментальная функция:

Ниже вы видите текст статьи по ссылке. По нему можно быстро понять ссылка достойна прочтения или нет

Просим обратить внимание, что текст по ссылке и здесь может не совпадать.

The Problem

To demonstrate common concurrency issues we are going to work on a bank account model:

class Account(models.Model):
    id = models.AutoField(
user = models.ForeignKey(
balance = models.IntegerField(

To get started we are going to implement a naive depositand withdrawmethods for an account instance:

def deposit(self, amount):
self.balance += amount

def withdraw(self, amount):
if amount > self.balance:
raise errors.InsufficientFunds()

    self.balance -= amount

This seems innocent enough and it might even pass unit tests and integration tests on localhost. But, what happens when two users perform actions on the same account at the same time?

  1. User A fetches the account — balance is 100$.
  2. User B fetches the account — balance is 100$.
  3. User B withdraws 30$ — balance is updated to 100$ — 30$ = 70$.
  4. User A deposits 50$ — balance is updated to 100$ + 50$ = 150$.

What happened here?

User B asked to withdraw 30$ and user A deposited 50$ — we expect the balance to be 120$, but we ended up with 150$.

Why did it happen?

At step 4, when user A updated the balance, the amount he had stored in memory was stale (user B had already withdrawn 30$).

To prevent this situation from happening we need to make sure the resource we are working on is not altered while we are working on it.

Лучшая Python рассылка

Разместим вашу рекламу

Пиши: mail@pythondigest.ru

Нашли опечатку?

Выделите фрагмент и отправьте нажатием Ctrl+Enter.

Система Orphus