Home > Software design >  How can I handle multiple requests at the same time in Django?
How can I handle multiple requests at the same time in Django?

Time:11-09

I'm currently writing an API in which a user could transfer money from their account to a phone but I'm facing an issue which is the user can call the API more than once at the same time and ask for transferring the money. Normally the balance of his account wouldn't be correct after the calls so I searched a lot and found out that I can use atomic transactions and lock the database. Now if the user uses the API for example twice, one of them runs correctly but the other one gets django.db.utils.OperationalError: database is locked error. Any idea how can I handle both of them correctly? (I could use a while and wait until the database gets unlocked but I rather don't do that)

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'}

CodePudding user response:

I'm guessing you're using SQLite database. It doesn't allow concurrent writes, i.e. more than one writing operations at a given time.

You have to options:

  1. Either switch to a different database
  2. Or increase the database timeout option in settings

Example:

# settings.py

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

This is not a scalable solution. Suppose, you've got many processes waiting for the write access, you may still get OperationalError if there are any processes still waiting after 60 seconds.

  • Related