Как я могу обрабатывать несколько запросов одновременно в Django?

В настоящее время я пишу API, в котором пользователь может перевести деньги со своего счета на телефон, но я столкнулся с проблемой, которая заключается в том, что пользователь может вызвать API более одного раза в одно и то же время и попросить перевести деньги. Обычно баланс его счета не будет корректным после этих вызовов, поэтому я много искал и выяснил, что я могу использовать атомарные транзакции и блокировать базу данных. Теперь, если пользователь использует API, например, дважды, один из них выполняется правильно, но другой получает ошибку django.db.utils.OperationalError: database is locked. Есть идеи, как я могу правильно обработать оба варианта? (Я мог бы использовать while и ждать, пока база данных разблокируется, но я предпочитаю этого не делать)

models.py

@transaction.atomic()
    def withdraw(self, amount, phone, username):
        property = transferLog.objects.filter(username=username).order_by('-time').select_for_update()[0]
        if property.property >= int(amount):
            self.username = username
            self.property = property.property - int(amount)
            self._from = username
            self._to = phone
            self.amount = int(amount)
            self.time = str(datetime.datetime.now())
            self.save()
            return {'result': 'success', 'message': 'transfer complete', 'remaining': self.property}
        else:
            return {'result': 'error', 'message': 'not enough money'}

Предполагаю, что вы используете базу данных SQLite. Она не допускает одновременной записи, т.е. более одной операции записи в одно и то же время.

У вас есть варианты:

  1. Либо переключитесь на другую базу данных
  2. Или увеличить опцию базы данных timeout в настройках

Пример:

# settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db.sqlite3',
        'OPTIONS': {
            'timeout': 60, # 1 minute
        }
    }
}

Это не масштабируемое решение. Предположим, у вас много процессов, ожидающих доступа на запись, вы все равно можете получить OperationalError, если есть процессы, все еще ожидающие через 60 секунд.

Вернуться на верх