如何在 Django 中同时处理多个请求?
How can I handle multiple requests at the same time in Django?
我目前正在编写一个 API,用户可以在其中将钱从他们的帐户转账到 phone,但我遇到了一个问题,即用户可以调用 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 数据库。它不允许并发写入,即在给定时间有多个写入操作。
您必须选择:
- 要么切换到不同的数据库
- 或者在设置中增加数据库
timeout
选项
示例:
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
'OPTIONS': {
'timeout': 60, # 1 minute
}
}
}
这不是一个可扩展的解决方案。假设,您有许多进程在等待写访问,如果 60 秒后仍有任何进程在等待,您可能仍会得到 OperationalError
。
我目前正在编写一个 API,用户可以在其中将钱从他们的帐户转账到 phone,但我遇到了一个问题,即用户可以调用 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 数据库。它不允许并发写入,即在给定时间有多个写入操作。
您必须选择:
- 要么切换到不同的数据库
- 或者在设置中增加数据库
timeout
选项
示例:
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
'OPTIONS': {
'timeout': 60, # 1 minute
}
}
}
这不是一个可扩展的解决方案。假设,您有许多进程在等待写访问,如果 60 秒后仍有任何进程在等待,您可能仍会得到 OperationalError
。